aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosNotification
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosNotification
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/cosNotification')
-rw-r--r--lib/cosNotification/AUTHORS4
-rw-r--r--lib/cosNotification/Makefile41
-rw-r--r--lib/cosNotification/doc/html/.gitignore0
-rw-r--r--lib/cosNotification/doc/man3/.gitignore0
-rw-r--r--lib/cosNotification/doc/man6/.gitignore0
-rw-r--r--lib/cosNotification/doc/pdf/.gitignore0
-rw-r--r--lib/cosNotification/doc/src/CosNotification.xml234
-rw-r--r--lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml79
-rw-r--r--lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml106
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml242
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml226
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml89
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml128
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml113
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml112
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml98
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml110
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml175
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml112
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml146
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml109
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml111
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml110
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml140
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml110
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml110
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml195
-rw-r--r--lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml65
-rw-r--r--lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml64
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml222
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml111
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml73
-rw-r--r--lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml227
-rw-r--r--lib/cosNotification/doc/src/Makefile254
-rw-r--r--lib/cosNotification/doc/src/book.gifbin0 -> 1081 bytes
-rw-r--r--lib/cosNotification/doc/src/book.xml48
-rw-r--r--lib/cosNotification/doc/src/ch_BNF.xml456
-rw-r--r--lib/cosNotification/doc/src/ch_QoS.xml251
-rw-r--r--lib/cosNotification/doc/src/ch_contents.xml74
-rw-r--r--lib/cosNotification/doc/src/ch_example.xml169
-rw-r--r--lib/cosNotification/doc/src/ch_install.xml146
-rw-r--r--lib/cosNotification/doc/src/ch_introduction.xml57
-rw-r--r--lib/cosNotification/doc/src/ch_system.xml83
-rw-r--r--lib/cosNotification/doc/src/cosNotificationApp.xml308
-rw-r--r--lib/cosNotification/doc/src/eventstructure.gifbin0 -> 89760 bytes
-rw-r--r--lib/cosNotification/doc/src/eventstructure.ps2462
-rw-r--r--lib/cosNotification/doc/src/fascicules.xml18
-rw-r--r--lib/cosNotification/doc/src/make.dep48
-rw-r--r--lib/cosNotification/doc/src/notes.gifbin0 -> 2005 bytes
-rw-r--r--lib/cosNotification/doc/src/notes.xml391
-rw-r--r--lib/cosNotification/doc/src/notificationFlow.gifbin0 -> 167734 bytes
-rw-r--r--lib/cosNotification/doc/src/notificationFlow.ps4372
-rw-r--r--lib/cosNotification/doc/src/part.xml42
-rw-r--r--lib/cosNotification/doc/src/part_notes.xml36
-rw-r--r--lib/cosNotification/doc/src/ref_man.gifbin0 -> 1530 bytes
-rw-r--r--lib/cosNotification/doc/src/ref_man.xml63
-rw-r--r--lib/cosNotification/doc/src/summary.html.src1
-rw-r--r--lib/cosNotification/doc/src/user_guide.gifbin0 -> 1581 bytes
-rw-r--r--lib/cosNotification/ebin/.gitignore0
-rw-r--r--lib/cosNotification/examples/.gitignore0
-rw-r--r--lib/cosNotification/include/.gitignore0
-rw-r--r--lib/cosNotification/info3
-rw-r--r--lib/cosNotification/priv/.gitignore0
-rw-r--r--lib/cosNotification/src/CosEvent.cfg20
-rw-r--r--lib/cosNotification/src/CosNotification.cfg0
-rw-r--r--lib/cosNotification/src/CosNotification.idl146
-rw-r--r--lib/cosNotification/src/CosNotification_Common.erl1210
-rw-r--r--lib/cosNotification/src/CosNotification_Definitions.hrl340
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin.cfg60
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin.idl275
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl670
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl142
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl721
-rw-r--r--lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl579
-rw-r--r--lib/cosNotification/src/CosNotifyComm.cfg0
-rw-r--r--lib/cosNotification/src/CosNotifyComm.idl83
-rw-r--r--lib/cosNotification/src/CosNotifyFilter.cfg6
-rw-r--r--lib/cosNotification/src/CosNotifyFilter.idl140
-rw-r--r--lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl125
-rw-r--r--lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl670
-rw-r--r--lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl578
-rw-r--r--lib/cosNotification/src/CosTypedEvent.idl57
-rw-r--r--lib/cosNotification/src/CosTypedNotification.idl109
-rw-r--r--lib/cosNotification/src/Makefile369
-rw-r--r--lib/cosNotification/src/PullerConsumer_impl.erl773
-rw-r--r--lib/cosNotification/src/PullerSupplier_impl.erl914
-rw-r--r--lib/cosNotification/src/PusherConsumer_impl.erl729
-rw-r--r--lib/cosNotification/src/PusherSupplier_impl.erl1052
-rw-r--r--lib/cosNotification/src/cosNotification.app.src120
-rw-r--r--lib/cosNotification/src/cosNotification.appup.src7
-rw-r--r--lib/cosNotification/src/cosNotificationApp.erl447
-rw-r--r--lib/cosNotification/src/cosNotificationAppComm.idl17
-rw-r--r--lib/cosNotification/src/cosNotificationComm.cfg3
-rw-r--r--lib/cosNotification/src/cosNotification_Filter.erl964
-rw-r--r--lib/cosNotification/src/cosNotification_Grammar.yrl166
-rw-r--r--lib/cosNotification/src/cosNotification_Scanner.erl268
-rw-r--r--lib/cosNotification/src/cosNotification_eventDB.erl1350
-rw-r--r--lib/cosNotification/vsn.mk11
98 files changed, 26065 insertions, 0 deletions
diff --git a/lib/cosNotification/AUTHORS b/lib/cosNotification/AUTHORS
new file mode 100644
index 0000000000..55d8059989
--- /dev/null
+++ b/lib/cosNotification/AUTHORS
@@ -0,0 +1,4 @@
+Original Authors:
+Niclas Eklund
+
+Contributors:
diff --git a/lib/cosNotification/Makefile b/lib/cosNotification/Makefile
new file mode 100644
index 0000000000..980f36191f
--- /dev/null
+++ b/lib/cosNotification/Makefile
@@ -0,0 +1,41 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1999-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include vsn.mk
+VSN=$(COSNOTIFICATION_VSN)
+
+# ----------------------------------------------------
+# Common Macros
+# ----------------------------------------------------
+# SUB_DIRECTORIES = src test examples doc/src
+# At the moment we don't have any example programs.
+SUB_DIRECTORIES = src doc/src
+
+SPECIAL_TARGETS =
+
+# ----------------------------------------------------
+# Default Subdir Targets
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_subdir.mk
diff --git a/lib/cosNotification/doc/html/.gitignore b/lib/cosNotification/doc/html/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/doc/html/.gitignore
diff --git a/lib/cosNotification/doc/man3/.gitignore b/lib/cosNotification/doc/man3/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/doc/man3/.gitignore
diff --git a/lib/cosNotification/doc/man6/.gitignore b/lib/cosNotification/doc/man6/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/doc/man6/.gitignore
diff --git a/lib/cosNotification/doc/pdf/.gitignore b/lib/cosNotification/doc/pdf/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/doc/pdf/.gitignore
diff --git a/lib/cosNotification/doc/src/CosNotification.xml b/lib/cosNotification/doc/src/CosNotification.xml
new file mode 100644
index 0000000000..22e9bcb27c
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotification.xml
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2002</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotification</title>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2002-02-05</date>
+ <rev>PA1</rev>
+ </header>
+ <module>CosNotification</module>
+ <modulesummary>This module export functions which return QoS and Admin Properties constants.</modulesummary>
+ <description>
+ <p>To get access to all definitions include necessary <c>hrl</c> files by using: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ </description>
+ <funcs>
+ <func>
+ <name>'EventReliability'() -> string()</name>
+ <fsummary>Return the EventReliability QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the EventReliability QoS identifier</p>
+ </desc>
+ </func>
+ <func>
+ <name>'BestEffort'() -> short()</name>
+ <fsummary>Return the BestEffort QoS value</fsummary>
+ <desc>
+ <p>This function returns the BestEffort QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'Persistent'() -> short()</name>
+ <fsummary>Return the Persistent QoS value</fsummary>
+ <desc>
+ <p>This function returns the Persistent QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'ConnectionReliability'() -> string()</name>
+ <fsummary>Return the ConnectionReliability QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the ConnectionReliability QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'Priority'() -> string()</name>
+ <fsummary>Return the Priority QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the Priority QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'LowestPriority'() -> short()</name>
+ <fsummary>Return the LowestPriority QoS value</fsummary>
+ <desc>
+ <p>This function returns the LowestPriority QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'HighestPriority'() -> short()</name>
+ <fsummary>Return the HighestPriority QoS value</fsummary>
+ <desc>
+ <p>This function returns the HighestPriority QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'DefaultPriority'() -> short()</name>
+ <fsummary>Return the DefaultPriority QoS value</fsummary>
+ <desc>
+ <p>This function returns the DefaultPriority QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'StartTime'() -> string()</name>
+ <fsummary>Return the StartTime QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the StartTime QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'StopTime'() -> string()</name>
+ <fsummary>Return the StopTime QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the StopTime QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'Timeout'() -> string()</name>
+ <fsummary>Return the Timeout QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the Timeout QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'OrderPolicy'() -> string()</name>
+ <fsummary>Return the OrderPolicy QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the OrderPolicy QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'AnyOrder'() -> short()</name>
+ <fsummary>Return the AnyOrder QoS value</fsummary>
+ <desc>
+ <p>This function returns the AnyOrder QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'FifoOrder'() -> short()</name>
+ <fsummary>Return the FifoOrder QoS value</fsummary>
+ <desc>
+ <p>This function returns the FifoOrder QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'PriorityOrder'() -> short()</name>
+ <fsummary>Return the PriorityOrder QoS value</fsummary>
+ <desc>
+ <p>This function returns the PriorityOrder QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'DeadlineOrder'() -> short()</name>
+ <fsummary>Return the DeadlineOrder QoS value</fsummary>
+ <desc>
+ <p>This function returns the DeadlineOrder QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'DiscardPolicy'() -> string()</name>
+ <fsummary>Return the DiscardPolicy QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the DiscardPolicy QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'LifoOrder'() -> short()</name>
+ <fsummary>Return the LifoOrder QoS value</fsummary>
+ <desc>
+ <p>This function returns the LifoOrder QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'RejectNewEvents'() -> short()</name>
+ <fsummary>Return the RejectNewEvents QoS value</fsummary>
+ <desc>
+ <p>This function returns the RejectNewEvents QoS value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'MaximumBatchSize'() -> string()</name>
+ <fsummary>Return the MaximumBatchSize QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the MaximumBatchSize QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'PacingInterval'() -> string()</name>
+ <fsummary>Return the PacingInterval QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the PacingInterval QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'StartTimeSupported'() -> string()</name>
+ <fsummary>Return the StartTimeSupported QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the StartTimeSupported QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'StopTimeSupported'() -> string()</name>
+ <fsummary>Return the StopTimeSupported QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the StopTimeSupported QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'MaxEventsPerConsumer'() -> string()</name>
+ <fsummary>Return the MaxEventsPerConsumer QoS identifier</fsummary>
+ <desc>
+ <p>This function returns the MaxEventsPerConsumer QoS identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'MaxQueueLength'() -> string()</name>
+ <fsummary>Return the MaxQueueLength Admin identifier</fsummary>
+ <desc>
+ <p>This function returns the MaxQueueLength Admin identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'MaxConsumers'() -> string()</name>
+ <fsummary>Return the MaxConsumers Admin identifier</fsummary>
+ <desc>
+ <p>This function returns the MaxConsumers Admin identifier.</p>
+ </desc>
+ </func>
+ <func>
+ <name>'MaxSuppliers'() -> string()</name>
+ <fsummary>Return the MaxSuppliers Admin identifier</fsummary>
+ <desc>
+ <p>This function returns the MaxSuppliers Admin identifier.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml b/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
new file mode 100644
index 0000000000..6e2a102051
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotification_&shy;AdminPropertiesAdmin</title>
+ <shorttitle>..._AdminPropertiesAdmin</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotification_AdminPropertiesAdmin</module>
+ <modulesummary>This module implements the OMG CosNotification::AdminPropertiesAdmin interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>All objects, which inherit this interface, export functions described in this module.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>get_admin(Object) -> AdminProperties</name>
+ <fsummary>Return a list of <c>AdminProperties</c>associated with the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>AdminProperties = [AdminProperty]</v>
+ <v>AdminProperty = #'CosNotification_Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ </type>
+ <desc>
+ <p>This operation returns sequence of name-value pairs which encapsulates the
+ current administrative properties of the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>set_admin(Object, AdminProperties) -> Reply</name>
+ <fsummary>Update the <c>AdminProperties</c>for the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>AdminProperties = [AdminProperty]</v>
+ <v>AdminProperty = #'CosNotification_Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>Reply = ok | {'EXCEPTION', CosNotification_UnsupportedAdmin}</v>
+ </type>
+ <desc>
+ <p>As input, this operation accepts a sequence of name-value pairs encapsulating the
+ desired administrative settings for the target object. If it is not possible to
+ set the given properties the exception <c>UnsupportedAdmin</c> will be raised.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml b/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml
new file mode 100644
index 0000000000..b7c19f664b
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotification_QoSAdmin.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>CosNotification_QoSAdmin</title>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotification_QoSAdmin</module>
+ <modulesummary>This module implements the OMG CosNotification::QoSAdmin interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>All objects, which inherit this interface, export functions described in this module.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>get_qos(Object) -> Reply</name>
+ <fsummary>Return a list of name-value pairs which encapsulates the current QoS settings for the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>Reply = [QoSProperty]</v>
+ <v>QoSProperty = #'CosNotification_Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ </type>
+ <desc>
+ <p>This operation returns a list of name-value pairs which encapsulates the current QoS settings
+ for the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>set_qos(Object, QoS) -> Reply</name>
+ <fsummary>Change the QoS settings for the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>QoS = [QoSProperty]</v>
+ <v>QoSProperty = #'CosNotification_Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotification_UnsupportedQoS'{qos_err}}</v>
+ <v>qos_err = PropertyErrorSeq</v>
+ <v>PropertyErrorSeq = [PropertyError]</v>
+ <v>PropertyError = #'CosNotification_PropertyError'{code, name, available_range}</v>
+ <v>code = 'UNSUPPORTED_PROPERTY' | 'UNAVAILABLE_PROPERTY' | 'UNSUPPORTED_VALUE' | 'UNAVAILABLE_VALUE' | 'BAD_PROPERTY' | 'BAD_TYPE' | 'BAD_VALUE'</v>
+ <v>name = string()</v>
+ <v>available_range = PropertyRange</v>
+ <v>PropertyRange = #CosNotification_PropertyRange{low_val, high_val}</v>
+ <v>low_val = high_val = #any</v>
+ </type>
+ <desc>
+ <p>To alter the current QoS settings for the target object this function must be used.
+ If it is not possible to set the requested QoS the <c>UnsupportedQoS</c>
+ exception is raised, which includes a sequence of <c>PropertyError</c>'s
+ describing which QoS, possible range and why is not allowed.</p>
+ </desc>
+ </func>
+ <func>
+ <name>validate_qos(Object, QoS) -> Reply</name>
+ <fsummary>Validate if the supplied QoS properties is valid for the target object </fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>QoS = [QoSProperty]</v>
+ <v>QoSProperty = #'Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>Reply = {ok, NamedPropertyRangeSeq} | {'EXCEPTION', CosNotification_UnsupportedQoS{}}</v>
+ <v>NamedPropertyRangeSeq = [NamedPropertyRange]</v>
+ <v>NamedPropertyRange = #CosNotification_NamedPropertyRange{name, range}</v>
+ <v>name = string()</v>
+ <v>range = #CosNotification_PropertyRange{low_val, high_val}</v>
+ <v>low_val = #any</v>
+ <v>high_val = #any</v>
+ </type>
+ <desc>
+ <p>The purpose of this operations is to check if a QoS setting is supported
+ by the target object and if so, the operation returns additional properties
+ which could be optionally added as well.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
new file mode 100644
index 0000000000..2cdb2d54a8
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ConsumerAdmin</title>
+ <shorttitle>..._ConsumerAdmin</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ConsumerAdmin</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ConsumerAdmin interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_MyID(ConsumerAdmin) -> AdminID</name>
+ <fsummary>Return the target object's Id</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>AdminID = long()</v>
+ </type>
+ <desc>
+ <p>The ID returned by the creating channel is equal to the value encapsulated by
+ this readonly attribute.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_MyChannel(ConsumerAdmin) -> Channel</name>
+ <fsummary>Return the ancestor channel</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>Channel = #objref</v>
+ </type>
+ <desc>
+ <p>The creating channel's reference is maintained by this readonly attribute.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_MyOperator(ConsumerAdmin) -> OpType</name>
+ <fsummary>Return the filtering schema used by the target object</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>OpType = 'AND_OP' | 'OR_OP'</v>
+ </type>
+ <desc>
+ <p>When <c>ConsumerAdmin's</c> are created an operation type,
+ i.e., <c>'AND_OP'</c> or <c>'OR_OP'</c>, is supplied, which determines
+ the semantics used by the target object concerning evaluation against
+ any associated <c>Filter</c> objects.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_priority_filter(ConsumerAdmin) -> MappingFilter</name>
+ <fsummary>Return the associated priority <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ConsumerAdmin = MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>If set, this operation returns the associated priority <c>MappingFilter</c>, otherwise
+ a <c>NIL</c> object reference is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_set_priority_filter(ConsumerAdmin, MappingFilter) -> ok</name>
+ <fsummary>Set the priority <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ConsumerAdmin = MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>To associate a priority <c>MappingFilter</c> with the target object this operation
+ must be used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_lifetime_filter(ConsumerAdmin) -> MappingFilter</name>
+ <fsummary>Return the associated lifetime <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ConsumerAdmin = MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>Unless a lifetime <c>MappingFilter</c> have been associated with the target object
+ a <c>NIL</c> object reference is returned by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_set_lifetime_filter(ConsumerAdmin, MappingFilter) -> ok</name>
+ <fsummary>Set the lifetime <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ConsumerAdmin = MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation associate a lifetime <c>MappingFilter</c> with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_pull_suppliers(ConsumerAdmin) -> ProxyIDSeq</name>
+ <fsummary>Return a list of all associated pull supplier Id:s</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>ProxyIDSeq = [ProxyID]</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the Id's for all <c>PullProxies</c> created
+ by the target object and still alive.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_push_suppliers(ConsumerAdmin) -> ProxyIDSeq</name>
+ <fsummary>Return a list of all associated push supplier Id:s</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>ProxyIDSeq = [ProxyID]</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>This attribute is similar to the <c>_get_pull_suppliers</c> attribute but maintains
+ the Id's for all <c>PushProxies</c> created by the target object and still alive.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_proxy_supplier(ConsumerAdmin, ProxyID) -> Reply</name>
+ <fsummary>Return the proxy supplier with matching Id</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>ProxyID = long()</v>
+ <v>Reply = Proxy | {'EXCEPTION', #'CosNotifyChannelAdmin_ProxyNotFound'{}}</v>
+ <v>Proxy = #objref</v>
+ </type>
+ <desc>
+ <p>If a proxy with the given Id exists the reference to the object is returned, but if
+ the object have terminated, or an incorrect Id is supplied, an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_notification_pull_supplier(ConsumerAdmin, ConsumerType) -> Reply</name>
+ <fsummary>Create a supplier proxy</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>ConsumerType = 'ANY_EVENT' | 'STRUCTURED_EVENT' | 'SEQUENCE_EVENT'</v>
+ <v>Reply = {Proxy, ProxyID}</v>
+ <v>Proxy = #objref</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>Determined by the parameter <c>ConsumerType</c>, a proxy which will
+ accept events of the defined type is created. Along with the object reference an
+ Id is returned. </p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_pull_supplier(ConsumerAdmin) -> Proxy</name>
+ <fsummary>Create a supplier proxy</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>Proxy = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a new proxy which accepts <c>#any{}</c> events.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_notification_push_supplier(ConsumerAdmin, ConsumerType) -> Reply</name>
+ <fsummary>Create a supplier proxy</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>ConsumerType = 'ANY_EVENT' | 'STRUCTURED_EVENT' | 'SEQUENCE_EVENT'</v>
+ <v>Reply = {Proxy, ProxyID}</v>
+ <v>Proxy = #objref</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>A proxy which accepts events of the type described by the parameter <c>ConsumerType</c>
+ is created by this operation. A unique Id is returned as an out parameter.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_push_supplier(ConsumerAdmin) -> Proxy</name>
+ <fsummary>Create a supplier proxy</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ <v>Proxy = #objref</v>
+ </type>
+ <desc>
+ <p>The object created by this function is a proxy which accepts <c>#any{}</c> events.</p>
+ </desc>
+ </func>
+ <func>
+ <name>destroy(ConsumerAdmin) -> ok</name>
+ <fsummary>Terminate the target object and all its children</fsummary>
+ <type>
+ <v>ConsumerAdmin = #objref</v>
+ </type>
+ <desc>
+ <p>To terminate the target object this operation should be used. The associated
+ <c>Channel</c> will be notified.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
new file mode 100644
index 0000000000..b6af2e2ca3
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;EventChannel</title>
+ <shorttitle>..._EventChannel</shorttitle>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_EventChannel</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::EventChannel interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_AdminPropertiesAdmin">CosNotification_AdminPropertiesAdmin</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_MyFactory(Channel) -> ChannelFactory</name>
+ <fsummary>Return the factory object which created the target object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>ChannelFactory = #objref</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the reference of the event channel
+ factory that created the target channel.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_default_consumer_admin(Channel) -> ConsumerAdmin</name>
+ <fsummary>Return the default consumer admin associated with the target object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>ConsumerAdmin = #objref</v>
+ </type>
+ <desc>
+ <p>This is a readonly attribute which maintains a reference to a default
+ <c>ConsumerAdmin</c> object associated with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_default_supplier_admin(Channel) -> SupplierAdmin</name>
+ <fsummary>Return the default supplier admin associated with the target object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>SupplierAdmin = #objref</v>
+ </type>
+ <desc>
+ <p>This is a readonly attribute which maintains a reference to a default
+ <c>SupplierAdmin</c> object associated with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_default_filter_factory(Channel) -> FilterFactory</name>
+ <fsummary>Return the default filter factory associated with the target object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>FilterFactory = #objref</v>
+ </type>
+ <desc>
+ <p>The default <c>FilterFactory</c> associated with the target channel
+ is maintained by this readonly attribute.</p>
+ </desc>
+ </func>
+ <func>
+ <name>new_for_consumers(Channel, OpType) -> Return</name>
+ <fsummary>Create a new <c>ConsumerAdmin</c>object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>OpType = 'AND_OP' | 'OR_OP'</v>
+ <v>Return = {ConsumerAdmin, AdminID}</v>
+ <v>ConsumerAdmin = #objref</v>
+ <v>AdminID = long()</v>
+ </type>
+ <desc>
+ <p>This operation creates a new instance of a <c>ConsumerAdmin</c> and supplies
+ an Id which may be used when invoking other operations exported by this module.
+ The returned object will inherit the Quality of Service properties of the
+ target channel.</p>
+ </desc>
+ </func>
+ <func>
+ <name>for_consumers(Channel) -> ConsumerAdmin</name>
+ <fsummary>Create a new <c>ConsumerAdmin</c>object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>ConsumerAdmin = #objref</v>
+ </type>
+ <desc>
+ <p>A new new instance of a <c>ConsumerAdmin</c> object is created but no
+ Id is returned. The returned object's operation type, i.e., <c>'AND_OP'</c> or <c>'OR_OP'</c>,
+ will be set to the value of the configuration parameter <c>filterOp</c>.
+ The target object's Quality of Service properties will be inherited by the
+ returned <c>ConsumerAdmin</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>new_for_suppliers(Channel, OpType) -> Return</name>
+ <fsummary>Create a new <c>SupplierAdmin</c>object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>OpType = 'AND_OP' | 'OR_OP'</v>
+ <v>Return = {SupplierAdmin, AdminID}</v>
+ <v>SupplierAdmin = #objref</v>
+ <v>AdminID = long()</v>
+ </type>
+ <desc>
+ <p>Enables us to create a new instance of a <c>SupplierAdmin</c>. An Id, which
+ may be used when invoking other operations exported by this module, is also
+ returned. The current Quality of Service settings associated with the target
+ object will be inherited by the <c>SupplierAdmin</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>for_suppliers(Channel) -> SupplierAdmin</name>
+ <fsummary>Create a new <c>SupplierAdmin</c>object</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>SupplierAdmin = #objref</v>
+ </type>
+ <desc>
+ <p>To create a new <c>SupplierAdmin</c> with the target object's current
+ Quality of Service settings we can use this function. The returned object's
+ operation type (<c>'AND_OP'</c> or <c>'OR_OP'</c>) will be determined by the
+ configuration variable <c>filterOp</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_consumeradmin(Channel, AdminID) -> ConsumerAdmin</name>
+ <fsummary>Return the <c>ConsumerAdmin</c>matching AdminID</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>AdminID = long()</v>
+ <v>ConsumerAdmin = #objref | {'EXCEPTION', #'CosNotifyChannelAdmin_AdminNotFound'{}}</v>
+ </type>
+ <desc>
+ <p>If the given Id is associated with a <c>ConsumerAdmin</c> the object reference
+ is returned. If such association never existed or the <c>ConsumerAdmin</c>
+ have terminated an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_supplieradmin(Channel, AdminID) -> SupplierAdmin</name>
+ <fsummary>Return the <c>SupplierAdmin</c>matching AdminID</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>AdminID = long()</v>
+ <v>SupplierAdmin = #objref | {'EXCEPTION', #'CosNotifyChannelAdmin_AdminNotFound'{}}</v>
+ </type>
+ <desc>
+ <p>Equal to the operation <c>get_consumeradmin/2</c> but a reference to
+ a <c>SupplierAdmin</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_all_consumeradmins(Channel) -> Reply</name>
+ <fsummary>Return a list of all <c>ConsumerAdmins</c>, currently active, Id:s</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>Reply = [AdminID]</v>
+ <v>AdminID = long()</v>
+ </type>
+ <desc>
+ <p>To get access to all <c>ConsumerAdmin</c> Id's created by the target object, and still
+ alive, this operation could be invoked.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_all_supplieradmins(Channel) -> Reply</name>
+ <fsummary>Return a list of all <c>SupplierAdmins</c>, currently active, Id:s</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ <v>Reply = [AdminID]</v>
+ <v>AdminID = long()</v>
+ </type>
+ <desc>
+ <p>Equal to the operation <c>get_all_consumeradmins/1</c> but returns
+ a list of all <c>SupplierAdmin</c> object ID's.</p>
+ </desc>
+ </func>
+ <func>
+ <name>destroy(Channel) -> ok</name>
+ <fsummary>Terminate the channel and all its children</fsummary>
+ <type>
+ <v>Channel = #objref</v>
+ </type>
+ <desc>
+ <p>The <c>destroy</c> operation will terminate the target channel and
+ all associated Admin objects.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
new file mode 100644
index 0000000000..01976954e7
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;EventChannelFactory</title>
+ <shorttitle>..._EventChannelFactory</shorttitle>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_EventChannelFactory</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::EventChannelFactory interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ </description>
+ <funcs>
+ <func>
+ <name>create_channel(ChannelFactory, InitialQoS, InitialAdmin) -> Return</name>
+ <fsummary>Create a new channel</fsummary>
+ <type>
+ <v>ChannelFactory = #objref</v>
+ <v>InitialQoS = CosNotification::QoSProperties</v>
+ <v>InitialAdmin = CosNotification::AdminProperties</v>
+ <v>Return = {EventChannel, ChannelID}</v>
+ <v>EventChannel = #objref</v>
+ <v>ChannelID = long()</v>
+ </type>
+ <desc>
+ <p>This operation creates a new event channel. Along with the channel
+ reference an id is returned which can be used when invoking other
+ operations exported by this module. The Quality of Service argument
+ supplied will be inherited by objects created by the channel. For more
+ information about QoS settings see the <c>User's Guide</c>.</p>
+ <p>If no QoS- and/or Admin-properties are supplied (i.e. empty list),
+ the <em>default</em> settings will be used. For more information, see the
+ User's Guide.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_all_channels(ChannelFactory) -> ChannelIDSeq</name>
+ <fsummary>Return all Id:s for channels, currently alive, created by the target object</fsummary>
+ <type>
+ <v>ChannelFactory = #objref</v>
+ <v>ChannelIDSeq = [long()]</v>
+ </type>
+ <desc>
+ <p>This operation returns a id sequence of all channel's created by this ChannelFactory.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_event_channel(ChannelFactory, ChannelID) -> Return</name>
+ <fsummary>Return the channel object associated with the given Id</fsummary>
+ <type>
+ <v>ChannelFactory = #objref</v>
+ <v>ChannelID = long()</v>
+ <v>Retrurn = EventChannel | {'EXCEPTION', #'CosNotifyChannelAdmin_ChannelNotFound'{}}</v>
+ <v>EventChannel = #objref</v>
+ </type>
+ <desc>
+ <p>This operation returns the EventChannel associated with the given id. If no channel is
+ associated with the id, i.e., never existed or have been terminated, an exception is raised.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
new file mode 100644
index 0000000000..69b1e78b82
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ProxyConsumer</title>
+ <shorttitle>..._ProxyConsumer</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ProxyConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ProxyConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_MyType(ProxyConsumer) -> ProxyType</name>
+ <fsummary>Return the proxy type</fsummary>
+ <type>
+ <v>ProxyConsumer = #objref</v>
+ <v>ProxyType = 'PUSH_ANY' | 'PULL_ANY' | 'PUSH_STRUCTURED' | 'PULL_STRUCTURED' | 'PUSH_SEQUENCE' | 'PULL_SEQUENCE'</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the enumerant describing the which type the target object
+ is. </p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_MyAdmin(ProxyConsumer) -> AdminObject</name>
+ <fsummary>return the associated <c>Admin</c>object</fsummary>
+ <type>
+ <v>ProxyConsumer = AdminObject = #objref</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the admin's reference which created the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_subscription_types(ProxyConsumer, ObtainInfoMode) -> EventTypeSeq</name>
+ <fsummary>Administer subscription types</fsummary>
+ <type>
+ <v>ProxyConsumer = #objref</v>
+ <v>ObtainInfoMode = 'ALL_NOW_UPDATES_OFF' | 'ALL_NOW_UPDATES_ON' | 'NONE_NOW_UPDATES_OFF' | 'NONE_NOW_UPDATES_ON'</v>
+ <v>EventTypeSeq = [EventType]</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ </type>
+ <desc>
+ <p>Depending on the input parameter <c>ObtainInfoMode</c>, this operation may return a
+ sequence of the <c>EventTypes</c> the target object is interested in receiving.
+ If <c>'ALL_NOW_UPDATES_OFF'</c> or <c>'ALL_NOW_UPDATES_ON'</c> is given a sequence will
+ be returned, otherwise not. If <c>'ALL_NOW_UPDATES_OFF'</c> or <c>'NONE_NOW_UPDATES_OFF'</c>
+ are issued the target object will not inform the associated <c>NotifySubscribe</c> object
+ when an update occurs. <c>'ALL_NOW_UPDATES_ON'</c> or <c>'NONE_NOW_UPDATES_ON'</c> will
+ result in that update information will be sent.</p>
+ </desc>
+ </func>
+ <func>
+ <name>validate_event_qos(ProxyConsumer, QoSProperties) -> Reply</name>
+ <fsummary>Check if certain Quality of Service properties can be added to events in the current context of the target object</fsummary>
+ <type>
+ <v>ProxyConsumer = #objref</v>
+ <v>QoSProperties = [QoSProperty]</v>
+ <v>QoSProperty = #'CosNotification_Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>Reply = {ok, NamedPropertyRangeSeq} | {'EXCEPTION', CosNotification_UnsupportedQoS{qos_err}}</v>
+ <v>NamedPropertyRangeSeq = [NamedPropertyRange]</v>
+ <v>NamedPropertyRange = #CosNotification_NamedPropertyRange{name, range}</v>
+ <v>name = string()</v>
+ <v>range = #CosNotification_PropertyRange{low_val, high_val}</v>
+ <v>low_val = #any</v>
+ <v>high_val = #any</v>
+ <v>qos_err = PropertyErrorSeq</v>
+ <v>PropertyErrorSeq = [PropertyError]</v>
+ <v>PropertyError = #'CosNotification_PropertyError'{code, name, available_range}</v>
+ <v>code = 'UNSUPPORTED_PROPERTY' | 'UNAVAILABLE_PROPERTY' | 'UNSUPPORTED_VALUE' | 'UNAVAILABLE_VALUE' | 'BAD_PROPERTY' | 'BAD_TYPE' | 'BAD_VALUE'</v>
+ <v>name = string()</v>
+ <v>available_range = PropertyRange</v>
+ <v>PropertyRange = #CosNotification_PropertyRange{low_val, high_val}</v>
+ <v>low_val = high_val = #any</v>
+ </type>
+ <desc>
+ <p>To check if certain Quality of Service properties can be added to events in
+ the current context of the target object this operation should be used. If we
+ cannot support the required settings an exception describing why will be raised.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
new file mode 100644
index 0000000000..29dc59871d
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ProxyPullConsumer</title>
+ <shorttitle>..._ProxyPullConsumer</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ProxyPullConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ProxyPullConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifyPublish">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxyConsumer">CosNotifyChannelAdmin_ProxyConsumer</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_any_pull_supplier(ProxyPullConsumer, PullSupplier) -> Reply</name>
+ <fsummary>Connect a supplier to the proxy</fsummary>
+ <type>
+ <v>ProxyPullConsumer = #objref</v>
+ <v>PullSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}} | {'EXCEPTION', #'CosEventChannelAdmin_TypeError'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects the given <c>PullSupplier</c> to the target object.
+ If a client is already connected the <c>AlreadyConnected</c> exception
+ will be raised. The client must support the operations <c>pull</c> and
+ <c>try_pull</c>, otherwise the <c>TypeError</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>suspend_connection(ProxyPullConsumer) -> Reply</name>
+ <fsummary>Suspend the connection between the client and the proxy</fsummary>
+ <type>
+ <v>ProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If we want to temporarily suspend the connection with the target object this
+ operation must be sued. If the connection already have been suspended or
+ no client have been connected an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>resume_connection(ProxyPullConsumer) -> Reply</name>
+ <fsummary>Resume a previously suspended connection with the proxy</fsummary>
+ <type>
+ <v>ProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyActive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If The connection have been suspended earlier we can invoke this operation to
+ reinstate the connection. If the connection already is active or no client
+ have been connected to the target object an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_pull_consumer(ProxyPullConsumer) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>ProxyPullConsumer = #objref</v>
+ </type>
+ <desc>
+ <p>Invoking this operation disconnects the client from the target object which
+ then terminates and inform its administrative parent.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
new file mode 100644
index 0000000000..daa0f3cc49
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ProxyPullSupplier</title>
+ <shorttitle>..._ProxyPullSupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ProxyPullSupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ProxyPullSupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxySupplier">CosNotifyChannelAdmin_ProxySupplier</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_any_pull_consumer(ProxyPullSupplier, PullConsumer) -> Reply</name>
+ <fsummary>Connect a consumer to the proxy</fsummary>
+ <type>
+ <v>ProxyPullSupplier = #objref</v>
+ <v>PullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects the given <c>PullConsumer</c> to the target object.
+ If a connection already exists the <c>AlreadyConnected</c> exception is
+ raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>pull(ProxyPullSupplier) -> Reply</name>
+ <fsummary>Pull an Any event from the proxy</fsummary>
+ <type>
+ <v>ProxyPullSupplier = #objref</v>
+ <v>Reply = #any | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation pulls next <c>#any{}</c> event, and blocks, if the target object
+ have no events to forward, until an event can be delivered. If no client have
+ been connected the <c>Disconnected</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>try_pull(ProxyPullSupplier) -> Reply</name>
+ <fsummary>Try and pull an Any event from the proxy</fsummary>
+ <type>
+ <v>ProxyPullSupplier = #objref</v>
+ <v>Reply = {#any, HasEvent} | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ <v>HasEvent = boolean()</v>
+ </type>
+ <desc>
+ <p>This operation pulls next event, but do not block if the target object
+ have no event to forward. If no client have
+ been connected the <c>Disconnected</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_pull_supplier(ProxyPullSupplier) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>ProxyPullSupplier = #objref</v>
+ </type>
+ <desc>
+ <p>Invoking this operation will cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
new file mode 100644
index 0000000000..63d3f53101
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ProxyPushConsumer</title>
+ <shorttitle>..._ProxyPushConsumer</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ProxyPushConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ProxyPushConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifyPublish">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxyConsumer">CosNotifyChannelAdmin_ProxyConsumer</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_any_push_supplier(ProxyPushConsumer, PushSupplier) -> Reply</name>
+ <fsummary>Connect a supplier to the proxy</fsummary>
+ <type>
+ <v>ProxyPushConsumer = #objref</v>
+ <v>PushSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PushSupplier</c> to the target object. If
+ a connection already exists the <c>AlreadyConnected</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>push(ProxyPushConsumer, Event) -> Reply</name>
+ <fsummary>Push an Any event to the proxy</fsummary>
+ <type>
+ <v>ProxyPushConsumer = #objref</v>
+ <v>Event = #any</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation pushes an <c>#any{}</c> event to the target object. If no client
+ have been connected the <c>Disconnected</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_push_consumer(ProxyPushConsumer) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>ProxyPushConsumer = #objref</v>
+ </type>
+ <desc>
+ <p>Invoking this operation will cause the target object to close the connection and
+ terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
new file mode 100644
index 0000000000..54d100c353
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ProxyPushSupplier</title>
+ <shorttitle>..._ProxyPushSupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ProxyPushSupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ProxyPushSupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmi</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxySupplier">CosNotifyChannelAdmin_ProxySupplier</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_any_push_consumer(ProxyPushSupplier, PushConsumer) -> Reply</name>
+ <fsummary>Connect a consumer to the proxy</fsummary>
+ <type>
+ <v>ProxyPushSupplier = #objref</v>
+ <v>PushConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}} | {'EXCEPTION', #'CosEventChannelAdmin_TypeError'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PushConsumer</c> to the target object. If
+ a connection already exists or the given client does not support
+ the operation <c>push</c> an exception, <c>AlreadyConnected</c> and
+ <c>TypeError</c> respectively, is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>suspend_connection(ProxyPushSupplier) -> Reply</name>
+ <fsummary>Suspend the connection between the proxy and the client</fsummary>
+ <type>
+ <v>ProxyPushSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation suspends the connection with the client object. If the connection
+ already is suspended or no client have been associated an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>resume_connection(ProxyPushSupplier) -> Reply</name>
+ <fsummary>Resume a previously suspended connection with the proxy</fsummary>
+ <type>
+ <v>ProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If a connection have been suspended earlier, calling this operation will resume the connection.
+ If the connection already is active or no client have been connected an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_push_supplier(ProxyPushSupplier) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>ProxyPushSupplier = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
new file mode 100644
index 0000000000..daf2aab388
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;ProxySupplier</title>
+ <shorttitle>..._ProxySupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_ProxySupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::ProxySupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_MyType(ProxySupplier) -> ProxyType</name>
+ <fsummary>Return the proxy type</fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>ProxyType = 'PUSH_ANY' | 'PULL_ANY' | 'PUSH_STRUCTURED' | 'PULL_STRUCTURED' | 'PUSH_SEQUENCE' | 'PULL_SEQUENCE'</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the enumerant describing the which type the target object
+ is.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_MyAdmin(ProxySupplier) -> AdminObject</name>
+ <fsummary>Return the target object's associated <c>Admin</c>object</fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>AdminObject = #objref</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the admin's reference which created the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_priority_filter(ProxySupplier) -> MappingFilter</name>
+ <fsummary>Return the target object's associated priority <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation returns the associated priority MappingFilter.
+ If no such object exist a <c>NIL</c> reference is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_set_priority_filter(ProxySupplier, MappingFilter) -> ok</name>
+ <fsummary>Set the target object's associated priority <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation associate a new priority MappingFilter with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_lifetime_filter(ProxySupplier) -> MappingFilter</name>
+ <fsummary>Return the target object's associated lifetime <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation returns the associated lifetime MappingFilter.
+ If no such object exist a <c>NIL</c> reference is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_set_lifetime_filter(ProxySupplier, MappingFilter) -> ok</name>
+ <fsummary>Set the target object's associated lifetime <c>MappingFilter</c></fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation associate a new lifetime MappingFilter with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_offered_types(ProxySupplier, ObtainInfoMode) -> EventTypeSeq</name>
+ <fsummary>Administer the type of events the proxy supplies</fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>ObtainInfoMode = 'ALL_NOW_UPDATES_OFF' | 'ALL_NOW_UPDATES_ON' | 'NONE_NOW_UPDATES_OFF' | 'NONE_NOW_UPDATES_ON'</v>
+ <v>EventTypeSeq = [EventType]</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ </type>
+ <desc>
+ <p>Depending on the input parameter <c>ObtainInfoMode</c>, this operation may return a
+ sequence of the <c>EventTypes</c> the target object is interested in receiving.
+ If <c>'ALL_NOW_UPDATES_OFF'</c> or <c>'ALL_NOW_UPDATES_ON'</c> is given a sequence will
+ be returned, otherwise not. If <c>'ALL_NOW_UPDATES_OFF'</c> or <c>'NONE_NOW_UPDATES_OFF'</c>
+ are issued the target object will not inform the associated <c>NotifySubscribe</c> object
+ when an update occurs. <c>'ALL_NOW_UPDATES_ON'</c> or <c>'NONE_NOW_UPDATES_ON'</c> will
+ result in that update information will be sent.</p>
+ </desc>
+ </func>
+ <func>
+ <name>validate_event_qos(ProxySupplier, QoSProperties) -> Reply</name>
+ <fsummary>Check if the QoS properties can be set</fsummary>
+ <type>
+ <v>ProxySupplier = #objref</v>
+ <v>QoSProperties = [QoSProperty]</v>
+ <v>QoSProperty = #'CosNotification_Property'{name, value}</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>Reply = {ok, NamedPropertyRangeSeq} | {'EXCEPTION', CosNotification_UnsupportedQoS{qos_err}}</v>
+ <v>NamedPropertyRangeSeq = [NamedPropertyRange]</v>
+ <v>NamedPropertyRange = #CosNotification_NamedPropertyRange{name, range}</v>
+ <v>name = string()</v>
+ <v>range = #CosNotification_PropertyRange{low_val, high_val}</v>
+ <v>low_val = #any</v>
+ <v>high_val = #any</v>
+ <v>qos_err = PropertyErrorSeq</v>
+ <v>PropertyErrorSeq = [PropertyError]</v>
+ <v>PropertyError = #'CosNotification_PropertyError'{code, name, available_range}</v>
+ <v>code = 'UNSUPPORTED_PROPERTY' | 'UNAVAILABLE_PROPERTY' | 'UNSUPPORTED_VALUE' | 'UNAVAILABLE_VALUE' | 'BAD_PROPERTY' | 'BAD_TYPE' | 'BAD_VALUE'</v>
+ <v>name = string()</v>
+ <v>available_range = PropertyRange</v>
+ <v>PropertyRange = #CosNotification_PropertyRange{low_val, high_val}</v>
+ <v>low_val = high_val = #any</v>
+ </type>
+ <desc>
+ <p>To check if certain Quality of Service properties can be added to events in
+ the current context of the target object this operation should be used. If we
+ cannot support the required settings an exception describing why will be raised.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
new file mode 100644
index 0000000000..aa9fae47df
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;SequenceProxyPullConsumer</title>
+ <shorttitle>..._SequenceProxyPullConsumer</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_SequenceProxyPullConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::SequenceProxyPullConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifyPublish">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxyConsumer">CosNotifyChannelAdmin_ProxyConsumer</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_sequence_pull_supplier(SequenceProxyPullConsumer, PullSupplier) -> Reply</name>
+ <fsummary>Connect a supplier to the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullConsumer = #objref</v>
+ <v>PullSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}} | {'EXCEPTION', #'CosEventChannelAdmin_TypeError'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PullSupplier</c> to the target object. If a
+ connection already exists or the supplied client does not support the functions
+ <c>pull_structured_events</c> and <c>try_pull_structured_events</c> an exception
+ is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>suspend_connection(SequenceProxyPullConsumer) -> Reply</name>
+ <fsummary>Suspend the connection with the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If a connection exist, invoking this operation will suspend the connection
+ until instructed otherwise. Otherwise, no client have been connected or this operation
+ already have been invoked an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>resume_connection(SequenceProxyPullConsumer) -> Reply</name>
+ <fsummary>Resume a previously suspended connection with the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If an connection have been suspended this operation must be used to resume the
+ connection. If the connection already is active or no client have been connected an
+ exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_sequence_pull_consumer(SequenceProxyPullConsumer) -> ok</name>
+ <fsummary>Close connection and terminate the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullConsumer = #objref</v>
+ </type>
+ <desc>
+ <p>This operation close the connection to the client and terminates the target object.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
new file mode 100644
index 0000000000..a46c53c9c1
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;SequenceProxyPullSupplier</title>
+ <shorttitle>..._SequenceProxyPullSupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_SequenceProxyPullSupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::SequenceProxyPullSupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxySupplier">CosNotifyChannelAdmin_ProxySupplier</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_sequence_pull_consumer(SequenceProxyPullSupplier, PullConsumer) -> Reply</name>
+ <fsummary>Connect a consumer to the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullSupplier = #objref</v>
+ <v>PullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PullConsumer</c> to the target object. If a connection
+ already exists an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>pull_structured_events(SequenceProxyPullSupplier, MaxEvents) -> Reply</name>
+ <fsummary>Pull structured events from the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullSupplier = #objref</v>
+ <v>MaxEvents = long()</v>
+ <v>Reply = EventBatch | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ <v>EventBatch = [StructuredEvent]</v>
+ <v>StructuredEvent = #'CosNotification_StructuredEvent'{header, filterable_data, remainder_of_body}</v>
+ <v>header = EventHeader</v>
+ <v>filterable_data = [#'CosNotification_Property'{name, value}]</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>remainder_of_body = #any</v>
+ <v>EventHeader = #'CosNotification_EventHeader'{fixed_header, variable_header}</v>
+ <v>fixed_header = FixedEventHeader</v>
+ <v>variable_header = OptionalHeaderFields</v>
+ <v>FixedEventHeader = #'CosNotification_FixedEventHeader'{event_type, event_name}</v>
+ <v>event_type = EventType</v>
+ <v>event_name = string()</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ <v>OptionalHeaderFields = [#'CosNotification_Property'{name, value}]</v>
+ </type>
+ <desc>
+ <p>A client use this operation to pull next event sequence of maximum length
+ <c>MaxEvents</c>. This operation is blocking and will not reply until the
+ requested amount of events can be delivered or the QoS property <c>PacingInterval</c>
+ is reached. For more information see the <c>User's Guide</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>try_pull_structured_events(SequenceProxyPullSupplier, MaxEvents) -> Reply</name>
+ <fsummary>Try to pull structured events from the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullSupplier = #objref</v>
+ <v>MaxEvents = long()</v>
+ <v>Reply = {EventBatch, HasEvent} | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ <v>HasEvent = boolean()</v>
+ <v>EventBatch = [StructuredEvent]</v>
+ <v>StructuredEvent = #'CosNotification_StructuredEvent'{header, filterable_data, remainder_of_body}</v>
+ <v>header = EventHeader</v>
+ <v>filterable_data = [#'CosNotification_Property'{name, value}]</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>remainder_of_body = #any</v>
+ <v>EventHeader = #'CosNotification_EventHeader'{fixed_header, variable_header}</v>
+ <v>fixed_header = FixedEventHeader</v>
+ <v>variable_header = OptionalHeaderFields</v>
+ <v>FixedEventHeader = #'CosNotification_FixedEventHeader'{event_type, event_name}</v>
+ <v>event_type = EventType</v>
+ <v>event_name = string()</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ <v>OptionalHeaderFields = [#'CosNotification_Property'{name, value}]</v>
+ </type>
+ <desc>
+ <p>This operation pulls an event sequence of the maximum length <c>MaxEvents</c>,
+ but do not block if the target object have no events to forward. The outparameter,
+ <c>HasEvent</c> is true if the sequence contain any events.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_sequence_pull_supplier(SequenceProxyPullSupplier) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullSupplier = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
new file mode 100644
index 0000000000..964d212715
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;SequenceProxyPushConsumer</title>
+ <shorttitle>..._SequenceProxyPushConsumer</shorttitle>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_&shy;SequenceProxyPushConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::SequenceProxyPushConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifyPublish">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxyConsumer">CosNotifyChannelAdmin_ProxyConsumer</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_sequence_push_supplier(SequenceProxyPushConsumer, PushSupplier) -> Reply</name>
+ <fsummary>Connect a supplier to the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPushConsumer = #objref</v>
+ <v>PushSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PushSupplier</c> to the target object. If a
+ connection already exists the <c>AlreadyConnected</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>push_structured_events(SequenceProxyPushConsumer, EventBatch) -> Reply</name>
+ <fsummary>Push a structured event to the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPushConsumer = #objref</v>
+ <v>EventBatch = [StructuredEvent]</v>
+ <v>StructuredEvent = #'CosNotification_StructuredEvent'{header, filterable_data, remainder_of_body}</v>
+ <v>header = EventHeader</v>
+ <v>filterable_data = [#'CosNotification_Property'{name, value}]</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>remainder_of_body = #any</v>
+ <v>EventHeader = #'CosNotification_EventHeader'{fixed_header, variable_header}</v>
+ <v>fixed_header = FixedEventHeader</v>
+ <v>variable_header = OptionalHeaderFields</v>
+ <v>FixedEventHeader = #'CosNotification_FixedEventHeader'{event_type, event_name}</v>
+ <v>event_type = EventType</v>
+ <v>event_name = string()</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ <v>OptionalHeaderFields = [#'CosNotification_Property'{name, value}]</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ </type>
+ <desc>
+ <p>A client must use this operation when it wishes to push a new sequence of events
+ to the target object. If no connection exists the <c>Disconnected</c> exception
+ is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_sequence_push_consumer(SequenceProxyPushConsumer) -> ok</name>
+ <fsummary>Close connection and terminate the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPushConsumer = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
new file mode 100644
index 0000000000..60dfa2c230
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;SequenceProxyPushSupplier</title>
+ <shorttitle>..._SequenceProxyPushSupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_&shy;SequenceProxyPushSupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::SequenceProxyPushSupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxySupplier">CosNotifyChannelAdmin_ProxySupplier</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_sequence_push_consumer(SequenceProxyPushSupplier, PushConsumer) -> Reply</name>
+ <fsummary>Connect a consumer to the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPushSupplier = #objref</v>
+ <v>PushConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}} | {'EXCEPTION', #'CosEventChannelAdmin_TypeError'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PushConsumer</c> to the target object. If a
+ connection already exists or the function <c>psuh_structured_events</c>
+ is not supported the exceptions <c>AlreadyConnected</c> or
+ <c>TypeError</c> will be raised respectively.</p>
+ </desc>
+ </func>
+ <func>
+ <name>suspend_connection(SequenceProxyPushSupplier) -> Reply</name>
+ <fsummary>Suspend the connection between the client and the target object</fsummary>
+ <type>
+ <v>SequenceProxyPushSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation suspends the connection between the client and the target object.
+ If no connection exists or the connection is already suspended an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>resume_connection(SequenceProxyPushSupplier) -> Reply</name>
+ <fsummary>Resume a previously suspended connection with the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If the connection have previously been suspended this operation must used
+ if we want to resume the connection. If no object have been connected or the connection
+ already is active an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_sequence_push_supplier(SequenceProxyPushSupplier) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>SequenceProxyPushSupplier = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
new file mode 100644
index 0000000000..070f9a3b92
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;StructuredProxyPullConsumer</title>
+ <shorttitle>..._StructuredProxyPullConsumer</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_&shy;StructuredProxyPullConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPullConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifyPublish">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxyConsumer">CosNotifyChannelAdmin_ProxyConsumer</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_structured_pull_supplier(StructuredProxyPullConsumer, PullSupplier) -> Reply</name>
+ <fsummary>Connect a supplier to the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullConsumer = #objref</v>
+ <v>PullSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}} | {'EXCEPTION', #'CosEventChannelAdmin_TypeError'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PullSupplier</c> to the target object. If a connection
+ already exists or the given client object does not support the functions
+ <c>pull_structured_event</c> and <c>try_pull_structured_event</c> an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>suspend_connection(StructuredProxyPullConsumer) -> Reply</name>
+ <fsummary>Suspend the connection between the target object and its client</fsummary>
+ <type>
+ <v>StructuredProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation suspends the connection between the target object and its client.
+ If no connection exists or already suspended an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>resume_connection(StructuredProxyPullConsumer) -> Reply</name>
+ <fsummary>Resume a previously suspended connection with the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If the connection have been suspended this operation must be used if we want
+ to resume the connection. If the connection already are active or no connection
+ have been created an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_structured_pull_consumer(StructuredProxyPullConsumer) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullConsumer = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
new file mode 100644
index 0000000000..4a454b224a
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;StructuredProxyPullSupplier</title>
+ <shorttitle>..._StructuredProxyPullSupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_&shy;StructuredProxyPullSupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPullSupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxySupplier">CosNotifyChannelAdmin_ProxySupplier</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_structured_pull_consumer(StructuredProxyPullSupplier, PullConsumer) -> Reply</name>
+ <fsummary>Connect a consumer to the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullSupplier = #objref</v>
+ <v>PullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PullConsumer</c> to the target object. If a connection
+ already exists the <c>AlreadyConnected</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>pull_structured_event(StructuredProxyPullSupplier) -> Reply</name>
+ <fsummary>Pull a structured event from the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullSupplier = #objref</v>
+ <v>Reply = StructuredEvent | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ <v>StructuredEvent = #'CosNotification_StructuredEvent'{header, filterable_data, remainder_of_body}</v>
+ <v>header = EventHeader</v>
+ <v>filterable_data = [#'CosNotification_Property'{name, value}]</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>remainder_of_body = #any</v>
+ <v>EventHeader = #'CosNotification_EventHeader'{fixed_header, variable_header}</v>
+ <v>fixed_header = FixedEventHeader</v>
+ <v>variable_header = OptionalHeaderFields</v>
+ <v>FixedEventHeader = #'CosNotification_FixedEventHeader'{event_type, event_name}</v>
+ <v>event_type = EventType</v>
+ <v>event_name = string()</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ <v>OptionalHeaderFields = [#'CosNotification_Property'{name, value}]</v>
+ </type>
+ <desc>
+ <p>This operation pulls next event from the target object; if an event cannot
+ be delivered this function blocks until an event arrives.</p>
+ </desc>
+ </func>
+ <func>
+ <name>try_pull_structured_event(StructuredProxyPullSupplier) -> Reply</name>
+ <fsummary>Try to pull a structured event from the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullSupplier = #objref</v>
+ <v>Reply = {StructuredEvent, HasEvent} | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ <v>HasEvent = boolean()</v>
+ <v>StructuredEvent = #'CosNotification_StructuredEvent'{header, filterable_data, remainder_of_body}</v>
+ <v>header = EventHeader</v>
+ <v>filterable_data = [#'CosNotification_Property'{name, value}]</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>remainder_of_body = #any</v>
+ <v>EventHeader = #'CosNotification_EventHeader'{fixed_header, variable_header}</v>
+ <v>fixed_header = FixedEventHeader</v>
+ <v>variable_header = OptionalHeaderFields</v>
+ <v>FixedEventHeader = #'CosNotification_FixedEventHeader'{event_type, event_name}</v>
+ <v>event_type = EventType</v>
+ <v>event_name = string()</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ <v>OptionalHeaderFields = [#'CosNotification_Property'{name, value}]</v>
+ </type>
+ <desc>
+ <p>This operation try to pull next event from the target object. If no event have arrived
+ an empty event is returned and the out parameter <c>HasEvent</c> is set to false. Otherwise,
+ the boolean flag is set to true and an valid event is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_structured_pull_supplier(StructuredProxyPullSupplier) -> ok</name>
+ <fsummary>Close connection and terminate the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPullSupplier = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
new file mode 100644
index 0000000000..db7f1ddb44
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;StructuredProxyPushConsumer</title>
+ <shorttitle>..._StructuredProxyPushConsumer</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_&shy;StructuredProxyPushConsumer</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPushConsumer interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifyPublish">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxyConsumer">CosNotifyChannelAdmin_ProxyConsumer</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_structured_push_supplier(StructuredProxyPushConsumer, PushSupplier) -> Reply</name>
+ <fsummary>Connect a supplier to the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPushConsumer = #objref</v>
+ <v>PushSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PushSupplier</c> to the target object. If a connection
+ already exists an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>push_structured_event(StructuredProxyPushConsumer, StructuredEvent) -> Reply</name>
+ <fsummary>Push a structured event to the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPushConsumer = #objref</v>
+ <v>StructuredEvent = #'CosNotification_StructuredEvent'{header, filterable_data, remainder_of_body}</v>
+ <v>header = EventHeader</v>
+ <v>filterable_data = [#'CosNotification_Property'{name, value}]</v>
+ <v>name = string()</v>
+ <v>value = #any</v>
+ <v>remainder_of_body = #any</v>
+ <v>EventHeader = #'CosNotification_EventHeader'{fixed_header, variable_header}</v>
+ <v>fixed_header = FixedEventHeader</v>
+ <v>variable_header = OptionalHeaderFields</v>
+ <v>FixedEventHeader = #'CosNotification_FixedEventHeader'{event_type, event_name}</v>
+ <v>event_type = EventType</v>
+ <v>event_name = string()</v>
+ <v>EventType = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ <v>OptionalHeaderFields = [#'CosNotification_Property'{name, value}]</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_Disconnected'{}}</v>
+ </type>
+ <desc>
+ <p>When a client want to push a new event to the target object this operation must be used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_structured_push_consumer(StructuredProxyPushConsumer) -> ok</name>
+ <fsummary>Close the connection and terminate the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPushConsumer = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
new file mode 100644
index 0000000000..b2dab10998
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;StructuredProxyPushSupplier</title>
+ <shorttitle>..._StructuredProxyPushSupplier</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_&shy;StructuredProxyPushSupplier</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPushSupplier interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifySubscribe</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyChannelAdmin_ProxySupplier">CosNotifyChannelAdmin_ProxySupplier</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>connect_structured_push_consumer(StructuredProxyPushSupplier, PushConsumer) -> Reply</name>
+ <fsummary>Connect a consumer to the proxy</fsummary>
+ <type>
+ <v>StructuredProxyPushSupplier = #objref</v>
+ <v>PushConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosEventChannelAdmin_AlreadyConnected'{}} | {'EXCEPTION', #'CosEventChannelAdmin_TypeError'{}}</v>
+ </type>
+ <desc>
+ <p>This operation connects a <c>PushConsumer</c> to the target object. If
+ a connection already exists or the function <c>push_structured_event</c>
+ is not supported by the client object an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>suspend_connection(StructuredProxyPushSupplier) -> Reply</name>
+ <fsummary>Suspend the connection with the target object</fsummary>
+ <type>
+ <v>StructuredProxyPushSupplier = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>This operation suspends the connection with the target object. If no connection
+ exists or the connection already is suspended an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>resume_connection(StructuredProxyPushSupplier) -> Reply</name>
+ <fsummary>Resume a previously suspended connection</fsummary>
+ <type>
+ <v>StructuredProxyPullConsumer = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{}} | {'EXCEPTION', #'CosNotifyChannelAdmin_NotConnected'{}}</v>
+ </type>
+ <desc>
+ <p>If the connection with the target object have been suspended this function
+ must be used to resume the connection. If no client have been connected or
+ the connection is active an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_structured_push_supplier(StructuredProxyPushSupplier) -> ok</name>
+ <fsummary>Close the connection and terminate the target object</fsummary>
+ <type>
+ <v>StructuredProxyPushSupplier = #objref</v>
+ </type>
+ <desc>
+ <p>This operation cause the target object to close the connection and terminate.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
new file mode 100644
index 0000000000..0f262accb8
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyChannelAdmin_&shy;SupplierAdmin</title>
+ <shorttitle>..._SupplierAdmin</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyChannelAdmin_SupplierAdmin</module>
+ <modulesummary>This module implements the OMG CosNotifyChannelAdmin::SupplierAdmin interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module also exports the functions described in:</p>
+ <list type="bulleted">
+ <item>
+ <p><seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyComm_NotifySubscribe">CosNotifyComm_NotifyPublish</seealso></p>
+ </item>
+ <item>
+ <p><seealso marker="CosNotifyFilter_FilterAdmin">CosNotifyFilter_FilterAdmin</seealso></p>
+ </item>
+ </list>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_MyID(SupplierAdmin) -> AdminID</name>
+ <fsummary>Return the objects Id</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>AdminID = long()</v>
+ </type>
+ <desc>
+ <p>When a <c>SupplierAdmin</c> object is created it is given a unique Id
+ by the creating channel. This readonly attribute maintains this Id.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_MyChannel(SupplierAdmin) -> Channel</name>
+ <fsummary>Return the objects associated channel</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>Channel = #objref</v>
+ </type>
+ <desc>
+ <p>The creating channel's reference is maintained by this readonly attribute.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_MyOperator(SupplierAdmin) -> OpType</name>
+ <fsummary>Return the filter scheme</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>OpType = 'AND_OP' | 'OR_OP'</v>
+ </type>
+ <desc>
+ <p>The Operation Type, which determines the semantics the target object will
+ use for any associated <c>Filters</c>, is maintained by this readonly attribute.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_pull_consumers(SupplierAdmin) -> ProxyIDSeq</name>
+ <fsummary>Return all associated pull consumers Id:s</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>ProxyIDSeq = [ProxyID]</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>A sequence of all associated <c>PullProxy</c> Id's is maintained by this
+ readonly attribute.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_push_consumers(SupplierAdmin) -> ProxyIDSeq</name>
+ <fsummary>Return all associated push consumers Id:s</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>ProxyIDSeq = [ProxyID]</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>This operation returns all <c>PushProxy</c> Id's created by the target
+ object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_proxy_consumer(SupplierAdmin, ProxyID) -> Reply</name>
+ <fsummary>Return the Proxy which corresponds to the given Id</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>ProxyID = long()</v>
+ <v>Reply = Proxy | {'EXCEPTION', #'CosNotifyChannelAdmin_ProxyNotFound'{}}</v>
+ <v>Proxy = #objref</v>
+ </type>
+ <desc>
+ <p>The Proxy which corresponds to the given Id is returned by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_notification_pull_consumer(SupplierAdmin, SupplierType) -> Reply</name>
+ <fsummary>Create a new proxy</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>SupplierType = 'ANY_EVENT' | 'STRUCTURED_EVENT' | 'SEQUENCE_EVENT'</v>
+ <v>Reply = {Proxy, ProxyID}</v>
+ <v>Proxy = #objref</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>This operation creates a new proxy and returns its object reference along with its ID.
+ The <c>SupplierType</c> parameter determines the event type accepted by the proxy.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_pull_consumer(SupplierAdmin) -> Proxy</name>
+ <fsummary>Create a new proxy</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>Proxy = #objref</v>
+ </type>
+ <desc>
+ <p>A proxy which accepts <c>#any{}</c> events is created by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_notification_push_consumer(SupplierAdmin, SupplierType) -> Reply</name>
+ <fsummary>Create a new proxy</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>SupplierType = 'ANY_EVENT' | 'STRUCTURED_EVENT' | 'SEQUENCE_EVENT'</v>
+ <v>Reply = {Proxy, ProxyID}</v>
+ <v>Proxy = #objref</v>
+ <v>ProxyID = long()</v>
+ </type>
+ <desc>
+ <p>Determined by the <c>SupplierType</c> parameter a compliant proxy is created and
+ its object reference along with its Id is returned by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>obtain_push_consumer(SupplierAdmin) -> Proxy</name>
+ <fsummary>Create a new proxy</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ <v>Proxy = #objref</v>
+ </type>
+ <desc>
+ <p>A proxy which accepts <c>#any{}</c> events is created by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>destroy(SupplierAdmin) -> ok</name>
+ <fsummary>Terminate the target object</fsummary>
+ <type>
+ <v>SupplierAdmin = #objref</v>
+ </type>
+ <desc>
+ <p>This operation terminates the SupplierAdmin object and notifies the creating channel
+ that the target object no longer is active.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml b/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml
new file mode 100644
index 0000000000..427ca87810
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyComm_NotifyPublish.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyComm_NotifyPublish</title>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyComm_NotifyPublish</module>
+ <modulesummary>This module implements the OMG CosNotifyComm::NotifyPublish interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>All objects, which inherit this interface, export functions described in this module.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>offer_change(Object, Added, Removed) -> Reply</name>
+ <fsummary>Inform the target object which type of events the supplier will deliver</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>Added = Removed = EventTypeSeq</v>
+ <v>EventTypeSeq = [type]</v>
+ <v>Reply = ok | {'EXCEPTION', CosNotifyComm_InvalidEventType{type}}</v>
+ <v>type = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ </type>
+ <desc>
+ <p>Objects supporting this interface can be informed by supplier objects about
+ which type of events that will be delivered in the future. This operation
+ accepts two parameters describing new and old event types respectively.
+ If any of the supplied event type names is syntactically incorrect an exception
+ is raised.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml b/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
new file mode 100644
index 0000000000..1ed7f860c0
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyComm_&shy;NotifySubscribe</title>
+ <shorttitle>..._NotifySubscribe</shorttitle>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyComm_NotifySubscribe</module>
+ <modulesummary>This module implements the OMG CosNotifyComm::NotifySubscribe interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>All objects, which inherit this interface, export functions described in this module.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>subscription_change(Object, Added, Removed) -> Reply</name>
+ <fsummary>Inform the target object which event types the client will and will not accept in the future</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>Added = Removed = EventTypeSeq</v>
+ <v>EventTypeSeq = [type]</v>
+ <v>Reply = ok | {'EXCEPTION', CosNotifyComm_InvalidEventType{type}}</v>
+ <v>type = #'CosNotification_EventType'{domain_name, type_name}</v>
+ <v>domain_name = type_name = string()</v>
+ </type>
+ <desc>
+ <p>This operation takes as input two sequences of event type names
+ specifying events the client will and will not accept in the future
+ respectively.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml b/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml
new file mode 100644
index 0000000000..dd894f2fea
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_Filter.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>CosNotifyFilter_Filter</title>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyFilter_Filter</module>
+ <modulesummary>This module implements the OMG CosNotifyFilter::Filter interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_constraint_grammar(Filter) -> Grammar</name>
+ <fsummary>Return which type of Grammar the Filter uses</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>Grammar = string()</v>
+ </type>
+ <desc>
+ <p>This operation returns which type of Grammar the Filter uses. Currently, only <c>"EXTENDED_TCL"</c> is supported.</p>
+ </desc>
+ </func>
+ <func>
+ <name>add_constraints(Filter, ConstraintExpSeq) -> Reply</name>
+ <fsummary>Add new constraints to the filter</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>ConstraintExpSeq = [Constraint]</v>
+ <v>ConstraintExp = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ <v>Reply = ConstraintInfoSeq | {'EXCEPTION', #'CosNotifyFilter_InvalidConstraint'{constr}}</v>
+ <v>constr = ConstraintExp</v>
+ <v>ConstraintInfoSeq = [ConstraintInfo]</v>
+ <v>ConstraintInfo = #'CosNotifyFilter_ConstraintInfo'{constraint_expression, constraint_id}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = long()</v>
+ </type>
+ <desc>
+ <p>Initially, Filters do not contain any constraints, hence, all events will be forwarded.
+ The <c>add_constraints/2</c> operation allow us to add constraints to the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>modify_constraints(Filter, ConstraintIDSeq, ConstraintInfoSeq) -> Reply</name>
+ <fsummary>Modify existing constraints</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>ConstraintIDSeq = [ConstraintID]</v>
+ <v>ConstraintID = long()</v>
+ <v>ConstraintInfoSeq = [ConstraintInfo]</v>
+ <v>ConstraintInfo = #'CosNotifyFilter_ConstraintInfo'{constraint_expression, constraint_id}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = long()</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyFilter_InvalidConstraint'{constr}} | {'EXCEPTION', #'CosNotifyFilter_ConstraintNotFound'{id}}</v>
+ <v>constr = ConstraintExp</v>
+ <v>id = long()</v>
+ <v>ConstraintExp = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ </type>
+ <desc>
+ <p>This operation is invoked by a client in order to modify the constraints associated
+ with the target object. The constraints related to the Id's in the parameter sequence
+ <c>ConstraintIDSeq</c> will, if all values are valid, be deleted. The <c>ConstraintInfoSeq</c>
+ parameter contains of Id-Expression pairs and a constraint matching one of the unique
+ Id's will, if all input values are correct, be updated. If the parameters contain incorrect
+ data en exception will be raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_constraints(Filter, ConstraintIDSeq) -> Reply</name>
+ <fsummary>Return all constraints which match the supplied Ids</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>ConstraintIDSeq = [ConstraintID]</v>
+ <v>ConstraintID = long()</v>
+ <v>Reply = ConstraintInfoSeq | {'EXCEPTION', #'CosNotifyFilter_ConstraintNotFound'{id}}</v>
+ <v>ConstraintInfoSeq = [ConstraintInfo]</v>
+ <v>ConstraintInfo = #'CosNotifyFilter_ConstraintInfo'{constraint_expression, constraint_id}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = id = long()</v>
+ </type>
+ <desc>
+ <p>This operation return a sequence of ConstraintInfo's, related to the given ConstraintID's,
+ associated with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_all_constraints(Filter) -> ConstraintInfoSeq</name>
+ <fsummary>Return all constraints associated with the target object</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>ConstraintInfoSeq = [ConstraintInfo]</v>
+ <v>ConstraintInfo = #'CosNotifyFilter_ConstraintInfo'{constraint_expression, constraint_id}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = long()</v>
+ </type>
+ <desc>
+ <p>All constraints, and their unique Id, associated with the target object will be returned by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_all_constraints(Filter) -> ok</name>
+ <fsummary>Remove all constraints associated with the target object</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ </type>
+ <desc>
+ <p>All constraints associated with the target object are removed by this operation and, since
+ the the target object no longer contain any constraints, true will always be the result of
+ any match operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>destroy(Filter) -> ok</name>
+ <fsummary>Terminate the target object</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation terminates the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>match(Filter, Event) -> Reply</name>
+ <fsummary>Match the Any event if it satisfies at least one constraint</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>Event = #any</v>
+ <v>Reply = boolean() | {'EXCEPTION', #'CosNotifyFilter_UnsupportedFilterableData'{}}</v>
+ </type>
+ <desc>
+ <p>This operation accepts an <c>#any{}</c> event and returns <c>true</c> if it satisfies
+ at least one constraint. If the event contains data of the wrong type, e.g., should be
+ a string() but in fact i a short(), an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>match_structured(Filter, Event) -> Reply</name>
+ <fsummary>Match the structured event if it satisfies at least one constraint</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>Event = #'CosNotification_StructuredEvent'{}</v>
+ <v>Reply = boolean() | {'EXCEPTION', #'CosNotifyFilter_UnsupportedFilterableData'{}}</v>
+ </type>
+ <desc>
+ <p>This operation is similar to the <c>match</c> operation but accepts structured
+ events instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>attach_callback(Filter, NotifySubscribe) -> CallbackID</name>
+ <fsummary>Connect NotifySubscribe object, which should be informed when the target object's constraints are updated</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>NotifySubscribe = #objref</v>
+ <v>CallbackID = long()</v>
+ </type>
+ <desc>
+ <p>This operation connects a NotifySubscribe object, which should be informed
+ when the target object's constraints are updated. A unique Id is returned
+ which must be stored if we ever want to detach the callback object in the future.</p>
+ </desc>
+ </func>
+ <func>
+ <name>detach_callback(Filter, CallbackID) -> Reply</name>
+ <fsummary>Disconnect the NotifySubscribe object with the given Id</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>CallbackID = long()</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyFilter_CallbackNotFound'{}}</v>
+ </type>
+ <desc>
+ <p>If the target object has an associated callback that matches the supplied
+ Id it will be removed and longer informed of any updates. If no object
+ with a matching Id is found an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_callbacks(Filter) -> CallbackIDSeq</name>
+ <fsummary>Return all NotifySubscribe Id's associated with the target object</fsummary>
+ <type>
+ <v>Filter = #objref</v>
+ <v>CallbackIDSeq = [CallbackID]</v>
+ <v>CallbackID = long()</v>
+ </type>
+ <desc>
+ <p>This operation returns a sequence of all connected NotifySubscribe object Id's.
+ If no callbacks are associated with the target object the list will be empty.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml b/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml
new file mode 100644
index 0000000000..ebbba8763d
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_FilterAdmin.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyFilter_FilterAdmin</title>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyFilter_FilterAdmin</module>
+ <modulesummary>This module implements the OMG CosNotifyFilter::FilterAdmin interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>All objects, which inherit this interface, export functions described in this module.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>add_filter(Object, Filter) -> FilterID</name>
+ <fsummary>Add a new filter to the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>Filter = #objref</v>
+ <v>FilterID = long()</v>
+ </type>
+ <desc>
+ <p>This operation connects a new <c>Filter</c> to the target object. This <c>Filter</c> will, together
+ with other associated <c>Filters</c>, be used to select events to forward. A unique Id is
+ returned and should be used if we no longer want to consult the given <c>Filter</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_filter(Object, FilterID) -> ok</name>
+ <fsummary>Remove a filter associated with the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>FilterID = long()</v>
+ </type>
+ <desc>
+ <p>If a certain <c>Filter</c> no longer should be associated with the target object
+ this operation must be used. Events will no longer be tested against the <c>Filter</c>
+ associated with the given Id.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_filter(Object, FilterID) -> Reply</name>
+ <fsummary>Return the filter with the given Id</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>FilterID = long()</v>
+ <v>Reply = Filter | {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}</v>
+ <v>Filter = #objref</v>
+ </type>
+ <desc>
+ <p>If the target object is associated with a <c>Filter</c> matching the given Id the
+ reference will be returned. If no such <c>Filter</c> is known by the target object
+ an exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_all_filters(Object) -> FilterIDSeq</name>
+ <fsummary>Return a list of all filter Id:s associated with the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ <v>FilterIDSeq = [FilterID]</v>
+ <v>FilterID = long()</v>
+ </type>
+ <desc>
+ <p>Id's for all <c>Filter</c> objects associated with the target object is
+ returned by this operation.</p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_all_filters(Object) -> ok</name>
+ <fsummary>Remove all filters from the target object</fsummary>
+ <type>
+ <v>Object = #objref</v>
+ </type>
+ <desc>
+ <p>If we want to remove all <c>Filters</c> associated with the target object we can use this function.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml b/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml
new file mode 100644
index 0000000000..c4712e481f
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_FilterFactory.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>CosNotifyFilter_FilterFactory</title>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyFilter_FilterFactory</module>
+ <modulesummary>This module implements the OMG CosNotifyFilter::FilterFactory interface.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ </description>
+ <funcs>
+ <func>
+ <name>create_filter(FilterFactory, Grammar) -> Reply</name>
+ <fsummary>Create a <c>Filter</c>object</fsummary>
+ <type>
+ <v>FilterFactory = #objref</v>
+ <v>Grammar = string()</v>
+ <v>Reply = Filter | {'EXCEPTION', #'CosNotifyFilter_InvalidGrammar'{}}</v>
+ <v>Filter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a new Filter object, under the condition
+ that Grammar given is supported. Currently, only <c>"EXTENDED_TCL"</c> is supported.</p>
+ </desc>
+ </func>
+ <func>
+ <name>create_mapping_filter(FilterFactory, Grammar) -> Reply</name>
+ <fsummary>Create a <c>MappingFilter</c>object</fsummary>
+ <type>
+ <v>FilterFactory = #objref</v>
+ <v>Grammar = string()</v>
+ <v>Reply = MappingFilter | {'EXCEPTION', #'CosNotifyFilter_InvalidGrammar'{}}</v>
+ <v>Filter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a new MappingFilter object, under the condition
+ that Grammar given is supported. Currently, only <c>"EXTENDED_TCL"</c> is supported.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml b/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml
new file mode 100644
index 0000000000..f5c6a75f3e
--- /dev/null
+++ b/lib/cosNotification/doc/src/CosNotifyFilter_MappingFilter.xml
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>CosNotifyFilter_MappingFilter</title>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date>2000-02-01</date>
+ <rev>1.0</rev>
+ </header>
+ <module>CosNotifyFilter_MappingFilter</module>
+ <modulesummary>This module implements the OMG CosNotifyFilter::MappingFilter interface.</modulesummary>
+ <description>
+ <p>The main purpose of this module is to match events against associated
+ constraints and return the value for the first constraint that returns
+ true for the given event. If all constraints return false the default value
+ will be returned.</p>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ </description>
+ <funcs>
+ <func>
+ <name>_get_constraint_grammar(MappingFilter) -> Grammar</name>
+ <fsummary>Return which type of Grammar the MappingFilter uses</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>Grammar = string()</v>
+ </type>
+ <desc>
+ <p>This operation returns which type of Grammar the MappingFilter uses.
+ Currently, only <c>"EXTENDED_TCL"</c> is supported.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_value_type(MappingFilter) -> CORBA::TypeCode</name>
+ <fsummary>Return the <c>CORBA::TypeCode</c>of the default value associated with the target object</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the <c>CORBA::TypeCode</c> of the default value
+ associated with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>_get_default_value(MappingFilter) -> #any</name>
+ <fsummary>Return the <c>#any{}</c> default value associated with the target object</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This readonly attribute maintains the <c>#any{}</c> default value associated with
+ the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>add_mapping_constraints(MappingFilter, MappingConstraintPairSeq) -> Reply</name>
+ <fsummary>Add new mapping constraints</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>MappingConstraintPairSeq = [MappingConstraintPair]</v>
+ <v>MappingConstraintPair = #'CosNotifyFilter_MappingConstraintPair'{constraint_expression, result_to_set}</v>
+ <v>constraint_expression = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ <v>result_to_set = #any</v>
+ <v>Reply = MappingConstraintInfoSeq | {'EXCEPTION', #'CosNotifyFilter_InvalidConstraint'{constr}} | {'EXCEPTION', #'CosNotifyFilter_InvalidValue'{constr, value}}</v>
+ <v>constr = ConstraintExp</v>
+ <v>ConstraintExp = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ <v>MappingConstraintInfoSeq = [MappingConstraintInfo]</v>
+ <v>MappingConstraintInfo = #'CosNotifyFilter_MappingConstraintInfo'{constraint_expression, constraint_id, value}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = long()</v>
+ <v>value = #any</v>
+ </type>
+ <desc>
+ <p>This operation add new mapping constraints, which will be used when trying to override
+ Quality of Service settings defined in the given event. If a constraint return true the
+ associated value will be returned, otherwise the default value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>modify_constraints(MappingFilter, ConstraintIDSeq, MappingConstraintInfoSeq) -> Reply</name>
+ <fsummary>Modify the constraints associated with the target object</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>ConstraintIDSeq = [ConstraintID]</v>
+ <v>ConstraintID = long()</v>
+ <v>MappingConstraintInfoSeq = [MappingConstraintInfo]</v>
+ <v>MappingConstraintInfo = #'CosNotifyFilter_MappingConstraintInfo'{constraint_expression, constraint_id, value}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = long()</v>
+ <v>value = #any</v>
+ <v>ConstraintInfoSeq = [ConstraintInfo]</v>
+ <v>ConstraintInfo = #'CosNotifyFilter_ConstraintInfo'{constraint_expression, constraint_id}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>constraint_id = long()</v>
+ <v>Reply = ok | {'EXCEPTION', #'CosNotifyFilter_InvalidConstraint'{constr}} | {'EXCEPTION', #'CosNotifyFilter_ConstraintNotFound'{id}} | {'EXCEPTION', #'CosNotifyFilter_InvalidValue'{constr, value}}</v>
+ <v>constr = ConstraintExp</v>
+ <v>id = long()</v>
+ <v>value = #any</v>
+ <v>ConstraintExp = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ </type>
+ <desc>
+ <p>The <c>ConstraintIDSeq</c> supplied should relate to constraints the caller wishes to
+ remove. If any of the supplied Id's are not found an exception will be raised. This
+ operation also accepts a sequence of <c>MappingConstraintInfo</c> which will be added.
+ If the target object cannot modify the constraints as requested an exception is raised
+ describing which constraint, and why, could not be updated.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_mapping_constraints(MappingFilter, ConstraintIDSeq) -> Reply</name>
+ <fsummary>Return the target object's associated constraints with given ID:s</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>ConstraintIDSeq = [ConstraintID]</v>
+ <v>ConstraintID = long()</v>
+ <v>Reply = MappingConstraintInfoSeq | {'EXCEPTION', #'CosNotifyFilter_ConstraintNotFound'{id}}</v>
+ <v>MappingConstraintInfoSeq = [MappingConstraintInfo]</v>
+ <v>MappingConstraintInfo = #'CosNotifyFilter_MappingConstraintInfo'{constraint_expression, constraint_id, value}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>ConstraintExp = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ <v>constraint_id = id = long()</v>
+ <v>value = #any</v>
+ </type>
+ <desc>
+ <p>When adding a new constraint a unique Id is returned, which is accepted as input for this
+ operation. The associated constraint is returned, but if no such Id exists an exception is raised. </p>
+ </desc>
+ </func>
+ <func>
+ <name>get_all_mapping_constraints(MappingFilter) -> MappingConstraintInfoSeq</name>
+ <fsummary>Return the target object's all associated constraints</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>MappingConstraintInfoSeq = [MappingConstraintInfo]</v>
+ <v>MappingConstraintInfo = #'CosNotifyFilter_MappingConstraintInfo'{constraint_expression, constraint_id, value}</v>
+ <v>constraint_expression = ConstraintExp</v>
+ <v>ConstraintExp = #'CosNotifyFilter_ConstraintExp'{event_types, constraint_expr}</v>
+ <v>event_types = #'CosNotification_EventTypeSeq'{}</v>
+ <v>constraint_expr = string()</v>
+ <v>constraint_id = long()</v>
+ <v>value = #any</v>
+ </type>
+ <desc>
+ <p>This operation returns a sequence of all unique Id's associated with the target object.
+ If no constraint have been added the sequence will be empty.</p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_all_mapping_constraints(MappingFilter) -> ok</name>
+ <fsummary>Remove all constraints associated with the target object</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation removes all constraints associated with the target object.</p>
+ </desc>
+ </func>
+ <func>
+ <name>destroy(MappingFilter) -> ok</name>
+ <fsummary>Terminate the target object</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ </type>
+ <desc>
+ <p>This operation terminates the target object. Remember to remove
+ this Filter from the objects it have been associated with.</p>
+ </desc>
+ </func>
+ <func>
+ <name>match(MappingFilter, Event) -> Reply</name>
+ <fsummary>Evaluate the given Any event with the Filter's constraints</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>Event = #any</v>
+ <v>Reply = {boolean(), #any} | {'EXCEPTION', #'CosNotifyFilter_UnsupportedFilterableData'{}}</v>
+ </type>
+ <desc>
+ <p>This operation evaluates <c>Any</c> events with the Filter's constraints,
+ and returns the value to use. The value is the default value if all constraints
+ returns false and the value associated with the first constraint returning true.</p>
+ </desc>
+ </func>
+ <func>
+ <name>match_structured(MappingFilter, Event) -> Reply</name>
+ <fsummary>Evaluate the given structured event with the Filter's constraints</fsummary>
+ <type>
+ <v>MappingFilter = #objref</v>
+ <v>Event = #'CosNotification_StructuredEvent'{}</v>
+ <v>Reply = {boolean(), #any} | {'EXCEPTION', #'CosNotifyFilter_UnsupportedFilterableData'{}}</v>
+ </type>
+ <desc>
+ <p>Similar to <c>match/2</c> but accepts a structured event as input.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/Makefile b/lib/cosNotification/doc/src/Makefile
new file mode 100644
index 0000000000..6abcf0ef1d
--- /dev/null
+++ b/lib/cosNotification/doc/src/Makefile
@@ -0,0 +1,254 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+VSN=$(COSNOTIFICATION_VSN)
+APPLICATION=cosNotification
+
+# ----------------------------------------------------
+# Include dependency
+# ----------------------------------------------------
+
+ifndef DOCSUPPORT
+include make.dep
+endif
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+XML_APPLICATION_FILES = ref_man.xml
+XML_REF3_FILES = \
+ cosNotificationApp.xml \
+ CosNotifyChannelAdmin_EventChannelFactory.xml \
+ CosNotifyChannelAdmin_EventChannel.xml \
+ CosNotification.xml \
+ CosNotification_QoSAdmin.xml \
+ CosNotification_AdminPropertiesAdmin.xml \
+ CosNotifyChannelAdmin_ConsumerAdmin.xml \
+ CosNotifyChannelAdmin_SupplierAdmin.xml \
+ CosNotifyComm_NotifyPublish.xml \
+ CosNotifyComm_NotifySubscribe.xml \
+ CosNotifyFilter_FilterAdmin.xml \
+ CosNotifyFilter_FilterFactory.xml \
+ CosNotifyFilter_Filter.xml \
+ CosNotifyFilter_MappingFilter.xml \
+ CosNotifyChannelAdmin_ProxyConsumer.xml \
+ CosNotifyChannelAdmin_ProxySupplier.xml \
+ CosNotifyChannelAdmin_ProxyPullConsumer.xml \
+ CosNotifyChannelAdmin_ProxyPullSupplier.xml \
+ CosNotifyChannelAdmin_ProxyPushConsumer.xml \
+ CosNotifyChannelAdmin_ProxyPushSupplier.xml \
+ CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml \
+ CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml \
+ CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml \
+ CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml \
+ CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml \
+ CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml \
+ CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml \
+ CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml \
+
+
+
+XML_PART_FILES = \
+ part.xml \
+ part_notes.xml
+XML_CHAPTER_FILES = \
+ ch_contents.xml \
+ ch_introduction.xml \
+ ch_install.xml \
+ ch_system.xml \
+ ch_BNF.xml \
+ ch_QoS.xml \
+ ch_example.xml \
+ notes.xml
+
+BOOK_FILES = book.xml
+
+TECHNICAL_DESCR_FILES =
+
+GIF_FILES = \
+ book.gif \
+ notes.gif \
+ ref_man.gif \
+ user_guide.gif \
+ eventstructure.gif \
+ notificationFlow.gif
+
+PS_FILES =
+
+# ----------------------------------------------------
+
+INTERNAL_HTML_FILES = $(TECHNICAL_DESCR_FILES:%.xml=$(HTMLDIR)/%.html)
+
+HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
+ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
+
+INFO_FILE = ../../info
+EXTRA_FILES = summary.html.src \
+ $(DEFAULT_GIF_FILES) \
+ $(DEFAULT_HTML_FILES) \
+ $(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \
+ $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
+
+MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
+
+ifdef DOCSUPPORT
+
+HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
+
+TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+
+else
+
+TEX_FILES_BOOK = \
+ $(BOOK_FILES:%.xml=%.tex)
+TEX_FILES_REF_MAN = $(XML_REF3_FILES:%.xml=%.tex) \
+ $(XML_APPLICATION_FILES:%.xml=%.tex)
+TEX_FILES_USERS_GUIDE = \
+ $(XML_CHAPTER_FILES:%.xml=%.tex)
+
+TOP_PDF_FILE = $(APPLICATION)-$(VSN).pdf
+
+TOP_PS_FILE = $(APPLICATION)-$(VSN).ps
+
+$(TOP_PDF_FILE): book.dvi ../../vsn.mk
+ $(DVI2PS) $(DVIPS_FLAGS) -f $< | $(DISTILL) $(DISTILL_FLAGS) > $@
+
+$(TOP_PS_FILE): book.dvi ../../vsn.mk
+ $(DVI2PS) $(DVIPS_FLAGS) -f $< > $@
+
+endif
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+XML_FLAGS +=
+DVIPS_FLAGS +=
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+$(HTMLDIR)/%.gif: %.gif
+ $(INSTALL_DATA) $< $@
+
+ifdef DOCSUPPORT
+
+docs: pdf html man
+
+$(TOP_PDF_FILE): $(XML_FILES)
+
+pdf: $(TOP_PDF_FILE)
+
+html: gifs $(HTML_REF_MAN_FILE)
+
+clean clean_docs:
+ rm -rf $(HTMLDIR)/*
+ rm -f $(MAN3DIR)/*
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f errs core *~
+
+else
+
+ifeq ($(DOCTYPE),pdf)
+docs: pdf
+else
+ifeq ($(DOCTYPE),ps)
+docs: ps
+else
+docs: html gifs man
+endif
+endif
+
+pdf: $(TOP_PDF_FILE)
+
+ps: $(TOP_PS_FILE)
+
+html: $(HTML_FILES) $(INTERNAL_HTML_FILES)
+
+clean clean_docs clean_tex:
+ rm -f $(TEX_FILES_USERS_GUIDE) $(TEX_FILES_REF_MAN) $(TEX_FILES_BOOK)
+ rm -f $(HTML_FILES) $(MAN3_FILES)
+ rm -f $(TOP_PDF_FILE) $(TOP_PS_FILE)
+ rm -f errs core *~ *xmls_output *xmls_errs $(LATEX_CLEAN)
+
+endif
+
+man: $(MAN3_FILES)
+
+gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+
+$(INDEX_TARGET): $(INDEX_SRC)
+ sed -e 's;%VSN%;$(VSN);' $(INDEX_SRC) > $(INDEX_TARGET)
+
+debug opt:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+ifdef DOCSUPPORT
+
+release_docs_spec: docs
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* \
+ $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
+ $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
+else
+
+ifeq ($(DOCTYPE),pdf)
+release_docs_spec: pdf
+ $(INSTALL_DIR) $(RELEASE_PATH)/pdf
+ $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELEASE_PATH)/pdf
+else
+ifeq ($(DOCTYPE),ps)
+release_docs_spec: ps
+ $(INSTALL_DIR) $(RELEASE_PATH)/ps
+ $(INSTALL_DATA) $(TOP_PS_FILE) $(RELEASE_PATH)/ps
+else
+release_docs_spec: docs
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
+ $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
+ $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3
+
+endif
+endif
+
+endif
+
+release_spec:
+
diff --git a/lib/cosNotification/doc/src/book.gif b/lib/cosNotification/doc/src/book.gif
new file mode 100644
index 0000000000..94b3868792
--- /dev/null
+++ b/lib/cosNotification/doc/src/book.gif
Binary files differ
diff --git a/lib/cosNotification/doc/src/book.xml b/lib/cosNotification/doc/src/book.xml
new file mode 100644
index 0000000000..fe311ee57c
--- /dev/null
+++ b/lib/cosNotification/doc/src/book.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE book SYSTEM "book.dtd">
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header titlestyle="normal">
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotification</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev>1.0</rev>
+ </header>
+ <insidecover>
+ </insidecover>
+ <pagetext>cosNotification</pagetext>
+ <preamble>
+ <contents level="2"></contents>
+ </preamble>
+ <parts lift="no">
+ <xi:include href="part.xml"/>
+ </parts>
+ <applications>
+ <xi:include href="ref_man.xml"/>
+ </applications>
+ <releasenotes>
+ <xi:include href="notes.xml"/>
+ </releasenotes>
+ <listofterms></listofterms>
+ <index></index>
+</book>
+
diff --git a/lib/cosNotification/doc/src/ch_BNF.xml b/lib/cosNotification/doc/src/ch_BNF.xml
new file mode 100644
index 0000000000..545280a1f4
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_BNF.xml
@@ -0,0 +1,456 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Filters and the Constraint Language BNF</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2000-04-13</date>
+ <rev></rev>
+ <file>ch_BNF.xml</file>
+ </header>
+
+ <section>
+ <title>Filters and the Constraint Language BNF</title>
+ <p>This chapter describes, the grammar supported by
+ <seealso marker="CosNotifyFilter_Filter">CosNotifyFilter_Filter</seealso> and
+ <seealso marker="CosNotifyFilter_MappingFilter">CosNotifyFilter_MappingFilter</seealso>,
+ and how to create and use filter objects.
+ </p>
+
+ <section>
+ <title>How to create filter objects</title>
+ <p>To be able to filter events we must create a filter and associate
+ it with one, or more, of the administrative or proxy objects. In the example
+ below, we choose to associate the filter with a ConsumerAdmin object.</p>
+ <code type="none">
+FilterFactory = cosNotificationApp:start_filter_factory(),
+Filter = 'CosNotifyFilter_FilterFactory':
+ create_filter(FilterFactory,"EXTENDED_TCL"),
+ConstraintInfoSeq = 'CosNotifyFilter_Filter':
+ add_constraints(Filter, ConstraintExpSeq),
+FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':
+ add_filter(AdminConsumer, Filter),
+ </code>
+ <p><c>"EXTENDED_TCL"</c> is the only grammar supported by Orber Notification
+ Service.</p>
+ <p>Depending on which operation type the Admin object uses, i.e.,
+ <c>'AND_OP'</c> or <c>'OR_OP'</c>, events will be tested using the
+ associated filter. The operation properties are:</p>
+ <p></p>
+ <list type="bulleted">
+ <item>
+ <p>'AND_OP' - must be approved by the proxy's <em>and</em> its parent admin's
+ filters. If all filters associated with an object (Admin or Proxy)
+ return false the event will be discarded. In this situation it is pointless
+ to try and verify with the other object's associated filters since the outcome
+ still would be the same.</p>
+ </item>
+ <item>
+ <p>'OR_OP' - if one of the object's (Admin or Proxy) filters return true, the event
+ will not be checked against any other filter associated with a proxy or its
+ parent admin. If a object's associated filters all return false,
+ the event will be forwarded to related proxies/admins, and
+ tested against any associated filters.</p>
+ </item>
+ </list>
+ <p>Initially, filters are empty and will always return true. Hence, we must
+ add constraints by using <c>'CosNotifyFilter_Filter':add_constraints/2</c>.
+ As input, the second argument must be a sequence of:</p>
+ <code type="none">
+#'CosNotifyFilter_ConstraintExp'{
+ event_types = [#'CosNotification_EventType'{
+ domain_name = string(),
+ type_name = string()}],
+ constraint_expr = string()}
+ </code>
+ <p>The <c>event_types</c> describes which types of events that should be matched using
+ the associated <c>constraint_expr</c>.</p>
+ <p>If a constraint expression is supposed to apply for all events, then the <c>type_name</c> can
+ be set to the special event type <c>%ALL</c> in a constraint's event type sequence. The
+ <c>domain_name</c> should be <c>""</c> or <c>"*"</c>.</p>
+ <p>In the following sections we will take a closer look on how to write
+ constraint expressions.</p>
+ </section>
+
+ <section>
+ <title>The CosNotification Constraint Language</title>
+ <p>The constraint language supported by the Notification Service is:</p>
+ <code type="none"><![CDATA[
+<constraint> := /* empty */
+ | <bool>
+
+<bool> := <bool_or>
+
+<bool_or> := <bool_or> or <bool_and>
+ | <bool_and>
+
+<bool_and> := <bool_and> and <bool_compare>
+ | <bool_compare>
+
+<bool_compare> := <expr_in> == <expr_in>
+ | <expr_in> != <expr_in>
+ | <expr_in> < <expr_in>
+ | <expr_in> <= <expr_in>
+ | <expr_in> > <expr_in>
+ | <expr_in> >= <expr_in>
+ | <expr_in>
+
+<expr_in> := <expr_twiddle> in <Ident> /* sequence only */
+ | <expr_twiddle>
+ | <expr_twiddle> in $ <Component> /* sequence only */
+
+<expr_twiddle> := <expr> ~ <expr> /* string data types only */
+ | <expr>
+
+<expr> := <expr> + <term>
+ | <expr> - <term>
+ | <term>
+
+<term> := <term> * <factor_not>
+ | <term> / <factor_not>
+ | <factor_not>
+
+<factor_not> := not <factor>
+ | <factor>
+
+<factor> := ( <bool_or> )
+ | exist <Ident>
+ | <Ident>
+ | <Number>
+ | - <Number>
+ | <String>
+ | TRUE
+ | FALSE
+ | + <Number>
+ | exist $ <Component>
+ | $ <Component>
+ | default $ <Component> /* discriminated unions only */
+
+<Component> := /* empty */
+ | . <CompDot>
+ | <CompArray>
+ | <CompAssoc>
+ | <Ident> <CompExt> /* run-time variable */
+
+<CompExt> := /* empty */
+ | . <CompDot>
+ | <CompArray>
+ | <CompAssoc>
+
+<CompDot> := <Ident> <CompExt>
+ | <CompPos>
+ | <UnionPos>
+ | _length /* only valid for arrays or sequences */
+ | _d /* discriminated unions only */
+ | _type_id /* only valid if possible to obtain */
+ | _repos_id /* only valid if possible to obtain */
+
+<CompArray> := [ <Digits> ] <CompExt>
+
+<CompAssoc> := ( <Ident> ) <CompExt>
+
+<CompPos> := <Digits> <CompExt>
+
+<UnionPos> := ( <UnionVal> ) <CompExt>
+
+<UnionVal> := /* empty */
+ | <Digits>
+ | - <Digits>
+ | + <Digits>
+ | <String>
+
+/* Character set issues */
+<Ident> :=<Leader> <FollowSeq>
+ | \\ < Leader> <FollowSeq>
+
+<FollowSeq> := /* <empty> */
+ | <FollowSeq> <Follow>
+
+<Number> := <Mantissa>
+ | <Mantissa> <Exponent>
+
+<Mantissa> := <Digits>
+ | <Digits> .
+ | . <Digits>
+ | <Digits> . <Digits>
+
+<Exponent> := <Exp> <Sign> <Digits>
+
+<Sign> := +
+ | -
+
+<Exp> := E
+ | e
+
+<Digits> := <Digits> <Digit>
+ | <Digit>
+
+<String> := ' <TextChars> '
+
+<TextChars> := /* <empty> */
+ | <TextChars> <TextChar>
+
+<TextChar> := <Alpha>
+ | <Digit>
+ | <Other>
+ | <Special>
+
+<Special> := \\\\
+ | \\'
+
+<Leader> := <Alpha>
+
+<Follow> := <Alpha>
+ | <Digit>
+ | _
+
+<Alpha> is the set of alphabetic characters [A-Za-z]
+<Digit> is the set of digits [0-9]
+<Other> is the set of ASCII characters that are not <Alpha>, <Digit>, or <Special>
+ ]]></code>
+ <p>In the absence of parentheses, the following precedence relations hold :</p>
+ <list type="ordered">
+ <item><c>()</c>, <c>exist</c>, <c>default</c>, <c>unary-sign</c></item>
+ <item><c>not</c></item>
+ <item><c>*</c>, <c>/</c></item>
+ <item><c>+</c>, <c>-</c></item>
+ <item><c>~</c></item>
+ <item><c>in</c></item>
+ <item><c>==</c>, <c>!=</c>, <c><![CDATA[<]]></c>, <c><![CDATA[<=]]></c>, <c>></c>, <c>>=</c></item>
+ <item><c>and</c></item>
+ <item><c>or</c></item>
+ </list>
+ </section>
+
+ <section>
+ <title>The Constraint Language Data Types</title>
+ <p>The Notification Service Constraint Language, defines how to write
+ constraint expressions, which can be used to filter events. The
+ representation does, however, differ slightly from ordinary Erlang terms.</p>
+ <p>When creating a <c>ConstraintExp</c>, the field <c>constraint_expr</c> must be
+ set to contain a string, e.g., <c><![CDATA["1 < 2"]]></c>. The Notification Service Constraint
+ Language, is designed to be able to filter structured and unstructured events
+ using the same constraint expression. The Constraint Language Types and Operations
+ can be divided into two sub-groups:</p>
+ <list type="bulleted">
+ <item>
+ <p>Basic - arithmetics, strings, constants, numbers etc.</p>
+ </item>
+ <item>
+ <p>Complex - accessing members of complex data types, such as unions.</p>
+ </item>
+ </list>
+ <p>Some of the basic types, e.g., integer, are self explanatory. Hence, they are not described further.</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle"><em>Type/Operation</em></cell>
+ <cell align="center" valign="middle"><em>Examples</em></cell>
+ <cell align="center" valign="middle"><em>Description</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>string</c></cell>
+ <cell align="left" valign="middle"><c>"'MyString'"</c></cell>
+ <cell align="left" valign="middle">Strings are represented as a sequence of zero or more <c><![CDATA[<TextChar>]]></c>s enclosed in single quotes, e.g., <c>'string'</c>.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>~</c></cell>
+ <cell align="left" valign="middle"><c>"'Sring1' ~ 'String2'"</c></cell>
+ <cell align="left" valign="middle">The operator <c>~</c>is called the substring operator and mean "String1 is contained within String2".</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>boolean</c></cell>
+ <cell align="left" valign="middle"><c>"TRUE == (('lang' ~ 'Erlang' + 'fun' ~ 'functional') >= 2)"</c></cell>
+ <cell align="left" valign="middle">Booleans may only be TRUE or FALSE, i.e., only capital letters. Expressions which evaluate to TRUE or FALSE can be summed up and matched, where TRUE equals 1 and FALSE 0.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>sequence</c></cell>
+ <cell align="left" valign="middle"><c>"myIntegerSequence[2]"</c></cell>
+ <cell align="left" valign="middle">The BNF use C/C++ notation, i.e., the example will return the <em>third</em>element.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_length</c></cell>
+ <cell align="left" valign="middle"><c>"myIntegerSequence._length"</c></cell>
+ <cell align="left" valign="middle">Returns the length of an sequence or array.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>in</c></cell>
+ <cell align="left" valign="middle"><c>"'Erlang' in $.FunctionalLanguages&shy;StringSeq"</c></cell>
+ <cell align="left" valign="middle">Returns <c>TRUE</c>if a given element is found in the given sequence. The element must be of a simple type and the same as the sequence is defined to contain.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>$</c></cell>
+ <cell align="left" valign="middle"><c>"$ == 40"</c></cell>
+ <cell align="left" valign="middle">Denote the current event as well as any run-time variables. If the event is unstructured and its contained value 40, the example will return <c>TRUE</c>.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>.</c></cell>
+ <cell align="left" valign="middle"><c>"$.MyStructMember == 40"</c></cell>
+ <cell align="left" valign="middle">The structure member operator <c>.</c>may be used to reference its members when the data refers to a named structure, discriminated union, or CORBA::Any data structure.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_type_id</c></cell>
+ <cell align="left" valign="middle"><c>"$._type_id == 'MyStruct'"</c></cell>
+ <cell align="left" valign="middle">Returns the unscoped IDL type name of the component. This operation is only valid if said information can be obtained.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_repos_id</c></cell>
+ <cell align="left" valign="middle"><c>"$._repos_id == 'IDL:MyModule/MyStruct:1.0'"</c></cell>
+ <cell align="left" valign="middle">Returns the RepositoryId of the component. This operation is only valid if said information can be obtained.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>_d</c></cell>
+ <cell align="left" valign="middle"><c>"$.eventUnion._d"</c></cell>
+ <cell align="left" valign="middle">May only be used when accessing discriminated unions and refers to the discriminator.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>exist</c></cell>
+ <cell align="left" valign="middle"><c>"exist $.eventUnion._d and $.eventUnion._d == 10"</c></cell>
+ <cell align="left" valign="middle">To avoid that a filtering of an event fails due to that, for example, we try to compare a union discriminator which does not exist, we can use this operator.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>default</c></cell>
+ <cell align="left" valign="middle"><c>"default $.eventUnion._d"</c></cell>
+ <cell align="left" valign="middle">If the <c>_d</c>operation is in conjunction with the <c>default</c>operation, TRUE will be returned if the union has a default member that is active.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>union</c></cell>
+ <cell align="left" valign="middle"><c>"$.(0) == 5"</c>eq. <c>"$.('zero') == 5"</c></cell>
+ <cell align="left" valign="middle">When the component refers to a union, with one of the cases defined as <c>case 0: short zero;</c>, we use <c>0</c>or <c>'zero'</c>. The result of the example is <c>TRUE</c>if the union has a discriminator set to <c>0</c>and the value <c>5</c>. If more than one case is defined to be<c>'zero'</c>, <c>$.('zero')</c>accepts both; <c>$.(0)</c>only returns <c>TRUE</c>if the discriminator is set to <c>0</c>. Leaving out the identifier, i.e., <c>$.()</c>, refers to the default value.</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>name-value pairs</c></cell>
+ <cell align="left" valign="middle"><c>"$.NameValueSeq('myID') == 5"</c>eq.<c>"$.NameValueSeq[1].name == 'myID' and $.NameValueSeq[1].value == 5"</c></cell>
+ <cell align="left" valign="middle">The Notification service makes extensive use of <c>name-value pairs</c>sequences within structured events, which allow us to via the identifier <c>name</c>access its <c>value</c>, as shown in the example.</cell>
+ </row>
+ <tcaption>Table 1: Type and Operator Examples</tcaption>
+ </table>
+ <p>In the next section we will take a closer look at how it is possible to write constraints using
+ different types of notation etc.</p>
+ </section>
+
+ <section>
+ <title>Accessing Data In Events</title>
+ <p>To filter events, the supplied constraints must describe the contents of
+ the events and desired values. We can, for example, state that we are only
+ interested in receiving events which are of type <em>CommunicationsAlarm</em>.
+ To be able to achieve this, the constraint must contain information
+ that points out which fields to compare with. Figure one illustrates a conceptual overview of a
+ structured event. The exact definition is found in the <c>CosNotification.idl</c> file.</p>
+ <marker id="eventstructure"></marker>
+ <image file="eventstructure.gif">
+ <icaption>
+Figure 1: The structure of a structured event.</icaption>
+ </image>
+ <p>The Notification Service supports different constraint expressions
+ notation:</p>
+ <list type="bulleted">
+ <item>
+ <p>Fully scoped, e.g., "$.header.fixed_header.event_type.type_name == 'CommunicationsAlarm'"</p>
+ </item>
+ <item>
+ <p>Short hand, e.g., "$type_name == 'CommunicationsAlarm'"</p>
+ </item>
+ <item>
+ <p>Positional Notation, e.g., "$.0.0.0.1 == 'CommunicationsAlarm'"</p>
+ </item>
+ </list>
+ <note>
+ <p>Which notation to use is up to the user, however, the fully scoped may
+ be easier to understand, but in some cases, if received from an ORB that do not populate ID:s of
+ named parts, the positional notation is the only option.</p>
+ </note>
+ <note>
+ <p>If a constraint, which access fields in a structured event structure,
+ is supposed to handle unstructured events as well, the CORBA::Any must contain
+ the same type of members.</p>
+ </note>
+ <p>How to filter against the fixed header fields, is described in the
+ table below.</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle">Field</cell>
+ <cell align="center" valign="middle">Fully Scoped Constraint</cell>
+ <cell align="center" valign="middle">Short Hand Constraint</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">type_name</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;type.type_name == 'Type'"</cell>
+ <cell align="left" valign="middle">"$type_name == 'Type'"</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">domain_name</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;type.domain_name == 'Domain'"</cell>
+ <cell align="left" valign="middle">"$domain_name == 'Domain'"</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">event_name</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;name == 'Event'"</cell>
+ <cell align="left" valign="middle">"$event_name == 'Event'"</cell>
+ </row>
+ <tcaption>Table 2: Fixed Header Constraint Examples</tcaption>
+ </table>
+ <p>If we are only interested in receiving events regarding 'Domain', 'Event'
+ and 'Type', the constraint can look like
+ <c>"$domain_name == 'Domain' and $event_name == 'Event' and $type_name == 'Type'"</c>.</p>
+ <p>The variable event header consists of a sequence of <em>name-value pairs</em>. One way to filter on these are to use a constraint that looks
+ like <c>"($.header.variable_header[1].name == 'priority' and $.header.variable_header[1].value > 0)"</c>. An easier way to
+ accomplish the same result is to use a constraint that treats the name-value
+ pair as an associative array, i.e., when given a name the corresponding
+ value is returned. Hence, instead we can use
+ <c>"$.header.variable_header(priority) > 0"</c>.</p>
+ <p>Accessing the event body is done in the same way as for the event header
+ fields. The user must, however, be aware of, that if a run-time variable
+ (<c>$variable</c>) is used data in the event header may take precedence.
+ The order of precedence is:</p>
+ <list type="ordered">
+ <item>Reserved, e.g., <c>$curtime</c></item>
+ <item>A simple-typed member of <c>$.header.fixed_header</c>.</item>
+ <item>Properties in <c>$.header.variable_header</c>.</item>
+ <item>Properties in <c>$.filterable_data</c>.</item>
+ <item>If no match is found it is translated to <c>$.variable</c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Mapping Filters</title>
+ <p>Mapping Filters may only be associated with Consumer Administrators or Proxy
+ Suppliers. The purpose of a Mapping Filter is to override Quality of Service
+ settings.</p>
+ <p>Initially, Mapping Filters are empty and will always return true. Hence, we must
+ add constraints by using <c>'CosNotifyFilter_MappingFilter':add_mapping_constraints/2</c>.
+ If a constraint matches, the associated value will be used instead of the
+ related Quality of Service system settings.</p>
+ <p>As input, the second argument must be a sequence of:</p>
+ <code type="none">
+#'CosNotifyFilter_MappingConstraintPair'{
+ constraint_expression = #'CosNotifyFilter_ConstraintExp'{
+ event_types = [#'CosNotification_EventType'{
+ domain_name = string(),
+ type_name = string()}],
+ constraint_expr = string()},
+ result_to_set = any()}
+ </code>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/ch_QoS.xml b/lib/cosNotification/doc/src/ch_QoS.xml
new file mode 100644
index 0000000000..fbc8622a62
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_QoS.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Quality Of Service and Admin Properties</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2000-05-29</date>
+ <rev></rev>
+ <file>ch_QoS.xml</file>
+ </header>
+
+ <section>
+ <title>Quality Of Service and Admin Properties</title>
+ <p>This chapter explains the allowed properties for
+ <seealso marker="CosNotification_QoSAdmin">CosNotification_QoSAdmin</seealso> and
+ <seealso marker="CosNotification_AdminPropertiesAdmin">CosNotification_AdminPropertiesAdmin</seealso>.
+ </p>
+
+ <section>
+ <title>Quality Of Service</title>
+ <p>The cosNotification application supports the following QoS settings:</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle"><em>QoS</em></cell>
+ <cell align="center" valign="middle"><em>Range</em></cell>
+ <cell align="center" valign="middle"><em>Default</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">EventReliability</cell>
+ <cell align="left" valign="middle">BestEffort/Persistent</cell>
+ <cell align="left" valign="middle">BestEffort</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ConnectionReliability</cell>
+ <cell align="left" valign="middle">BestEffort/Persistent</cell>
+ <cell align="left" valign="middle">BestEffort</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Priority</cell>
+ <cell align="left" valign="middle">+/-32767</cell>
+ <cell align="left" valign="middle">0</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">OrderPolicy</cell>
+ <cell align="left" valign="middle">Any-, Fifo-, Priority- and Deadline-Order</cell>
+ <cell align="left" valign="middle">PriorityOrder</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">DiscardPolicy</cell>
+ <cell align="left" valign="middle">RejectNewEvents, Any-, Fifo-, Lifo-, Priority- and Deadline-Order</cell>
+ <cell align="left" valign="middle">RejectNewEvents</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">MaximumBatchSize</cell>
+ <cell align="left" valign="middle">long() > 0</cell>
+ <cell align="left" valign="middle">1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">PacingInterval</cell>
+ <cell align="left" valign="middle">TimeBase::TimeT (see cosTime)</cell>
+ <cell align="left" valign="middle">0</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">StartTimeSupported</cell>
+ <cell align="left" valign="middle">boolean</cell>
+ <cell align="left" valign="middle">false</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">StopTimeSupported</cell>
+ <cell align="left" valign="middle">boolean</cell>
+ <cell align="left" valign="middle">false</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">MaxEventsPerConsumer</cell>
+ <cell align="left" valign="middle">long() > 0</cell>
+ <cell align="left" valign="middle">100</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Timeout</cell>
+ <cell align="left" valign="middle">TimeBase::TimeT (see cosTime)</cell>
+ <cell align="left" valign="middle">No timeout</cell>
+ </row>
+ <tcaption>Table 1: Supported QoS Settings</tcaption>
+ </table>
+ <br></br>
+ <br></br>
+ <br></br>
+ <br></br>
+ <p><em>Comments on the table 'Supported QoS Settings':</em></p>
+ <taglist>
+ <tag><em>EventReliability</em></tag>
+ <item>To allow full Persistent EventReliability, every event must
+ be stored in a stable storage which would create a relatively
+ huge overhead. Hence, only lightweight version of the Persistent
+ QoS is supported. The configuration parameters <c>max_events</c>,
+ <c>interval_events</c> and <c>timeout_events</c> determine
+ the behavior of this setting.</item>
+ <tag><em>ConnectionReliability</em></tag>
+ <item>If this QoS is set to BestEffort and a client object returns anything
+ other than <c>ok</c> to its associated Proxy, the Proxy will discard
+ all events and terminate. Using Persistent and anything other than <c>ok</c>
+ is returned, events will be dropped but the proxy will retry later when
+ next delivery is due. A child may not have Persistent while its parent
+ has BestEffort QoS set, e.g., Proxy vs. Admin. If <c>OBJECT_NOT_EXIST</c>,
+ <c>NO_PERMISSION</c> or <c>CosEventComm_Disconnected</c> is thrown,
+ the associated object will terminate even if this parameter is
+ set to Persistent.</item>
+ <tag><em>Priority</em></tag>
+ <item>This QoS will treat all events as if they have the Priority equal to
+ current value, unless the event itself contains a Priority setting,
+ this event will be treated accordingly. Note: for this property to
+ have any effect, the DiscardPolicy and/or OrderPolicy must be set
+ to PriorityOrder.</item>
+ <tag><em>OrderPolicy</em></tag>
+ <item>If set to PriorityOrder, events with the highest Priority will be
+ delivered first. Deadline order will forward events with shortest
+ expiry time first. If two events have the same priority, they will be
+ delivered in FIFO-order.</item>
+ <tag><em>DiscardPolicy</em></tag>
+ <item>If set to PriorityOrder and MaxEventsPerConsumer limit is
+ reached, events
+ with the lowest Priority will be discarded first. Deadline order will
+ discard events with shortest expiry time first.</item>
+ <tag><em>MaximumBatchSize</em></tag>
+ <item>Only valid if the object is supposed to handle a sequence of structured
+ events and determines the largest amount of events that may be passed
+ each time.</item>
+ <tag><em>PacingInterval</em></tag>
+ <item>Determines how long an object will wait before forwarding a structured
+ event sequence of length equal to, or less than MaximumBatchSize.
+ If set to 0, which is the default behavior, no timeout is used and
+ the events are forwarded when the MaximumBatchSize is reached.</item>
+ <tag><em>StartTimeSupported</em></tag>
+ <item>If set to true events which contains the QoS Property <c>StartTime</c>
+ (TimeBase::UtcT - absolute time) will not be delivered until the
+ StartTime value have been exceeded. See also the <c>cosTime</c> application.</item>
+ <tag><em>StopTimeSupported</em></tag>
+ <item>If set to true, events which contain the QoS Properties <c>StopTime</c>
+ (TimeBase::UtcT - absolute time) or <c>Timeout</c> (TimeBase::TimeT -
+ relative time) will be discarded if the object has not been able to
+ deliver the event in time. See also the <c>cosTime</c> application.</item>
+ <tag><em>MaxEventsPerConsumer</em></tag>
+ <item>The maximum number of events the associated object may store before discarding
+ events in the way described by the DiscardPolicy.</item>
+ <tag><em>Timeout</em></tag>
+ <item>If this QoS property is not included in the event, and the Property
+ <c>StopTimeSupported</c> equals true, this setting will be applied
+ if events cannot be delivered within its time limit.</item>
+ </taglist>
+ <warning>
+ <p>Several of the above QoS Properties can be changed during run-time but we strongly advice
+ not to since, if a relatively large amount of events are waiting for delivery, some of the
+ QoS settings would require a total reorder of the events. The QoS property <c>ConnectioReliability</c>
+ may <em>never</em> be updated during run-time since it may cause deadlock. Run-time, in this case,
+ means activating the Channel by sending the first event.</p>
+ </warning>
+ </section>
+
+ <section>
+ <title>Setting Quality Of Service</title>
+ <p>Assume we have a Consumer Admin object which we want to change
+ the current Quality of Service. Typical usage:</p>
+ <code type="none">
+QoSPersistent =
+ [#'CosNotification_Property'
+ {name='CosNotification':'ConnectionReliability'(),
+ value=any:create(orber_tc:short(),
+ 'CosNotification':'Persistent'())}],
+'CosNotification_QoSAdmin':set_qos(Ch, QoSPersistent),
+ </code>
+ <p>If it is not possible to set the requested QoS the <c>UnsupportedQoS</c>
+ exception is raised, which includes a sequence of <c>PropertyError</c>'s
+ describing which QoS, possible range and why is not allowed. The error
+ codes are:</p>
+ <list type="bulleted">
+ <item>UNSUPPORTED_PROPERTY - QoS not supported for this type of target object.</item>
+ <item>UNAVAILABLE_PROPERTY - due to current QoS settings the given property
+ is not allowed.</item>
+ <item>UNSUPPORTED_VALUE - property value out of range; valid range is returned.</item>
+ <item>UNAVAILABLE_VALUE - due to current QoS settings the given value is
+ not allowed; valid range is returned.</item>
+ <item>BAD_PROPERTY - unrecognized property.</item>
+ <item>BAD_TYPE - type of supplied property is incorrect.</item>
+ <item>BAD_VALUE - illegal value.</item>
+ </list>
+ <p>The CosNotification_QoSAdmin interface also supports an operation
+ called <c>validate_qos/2</c>. The purpose of this operations is to check
+ if a QoS setting is supported by the target object and if so, the operation
+ returns additional properties which could be optionally added as well.</p>
+ </section>
+
+ <section>
+ <title>Admin Properties</title>
+ <p>The cosNotification application supports the following Admin Properties:</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle"><em>Property</em></cell>
+ <cell align="center" valign="middle"><em>Range</em></cell>
+ <cell align="center" valign="middle"><em>Default</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">MaxQueueLength</cell>
+ <cell align="left" valign="middle">0</cell>
+ <cell align="left" valign="middle">0</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">MaxConsumers</cell>
+ <cell align="left" valign="middle">long() >= 0</cell>
+ <cell align="left" valign="middle">0</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">MaxSuppliers</cell>
+ <cell align="left" valign="middle">long() >= 0</cell>
+ <cell align="left" valign="middle">0</cell>
+ </row>
+ <tcaption>Table 2: Supported Admin Properties</tcaption>
+ </table>
+ <p>According to the OMG specification the default values for Admin Properties
+ is supposed to be <c>0</c>, which means that no limit applies to these
+ properties.</p>
+ <note>
+ <p>Admin Properties can only be set on a Channel Object level, i.e.,
+ they will not have an impact on any Admin or Proxy Objects. Currently,
+ setting the Admin Property <c>MaxQueueLength</c> have no effect since
+ we cannot discard events accordingly to the Quality of Service Property
+ <c>DiscardPolicy</c>.</p>
+ </note>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/ch_contents.xml b/lib/cosNotification/doc/src/ch_contents.xml
new file mode 100644
index 0000000000..e5505951bf
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_contents.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>The cosNotification Application</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev>1.0</rev>
+ <file>ch-contents.xml</file>
+ </header>
+
+ <section>
+ <title>Content Overview</title>
+ <p>The cosNotification documentation is divided into three sections:
+ </p>
+ <list type="bulleted">
+ <item>
+ <p>PART ONE - The User's Guide
+ <br></br>
+Description of the cosNotification Application including
+ services and a small tutorial demonstrating
+ the development of a simple service.</p>
+ </item>
+ <item>
+ <p>PART TWO - Release Notes
+ <br></br>
+A concise history of cosNotification.</p>
+ </item>
+ <item>
+ <p>PART THREE - The Reference Manual
+ <br></br>
+ A quick reference guide, including a
+ brief description, to all the functions available in cosNotification.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Brief Description of the User's Guide</title>
+ <p>The User's Guide contains the following parts:</p>
+ <list type="bulleted">
+ <item>
+ <p>cosNotification overview</p>
+ </item>
+ <item>
+ <p>cosNotification installation</p>
+ </item>
+ <item>
+ <p>A tutorial example</p>
+ </item>
+ </list>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/ch_example.xml b/lib/cosNotification/doc/src/ch_example.xml
new file mode 100644
index 0000000000..8cb12bd241
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_example.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotification Examples</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev>A</rev>
+ <file>ch_example.xml</file>
+ </header>
+
+ <section>
+ <title>A Tutorial on How to Create a Simple Service</title>
+
+ <section>
+ <title>Interface Design</title>
+ <p>To use the cosNotification application <em>clients</em> must be implemented.
+ There are twelve types of clients: </p>
+ <list type="bulleted">
+ <item>Structured Push Consumer</item>
+ <item>Sequence Push Consumer </item>
+ <item>Any Push Consumer</item>
+ <item>Structured Pull Consumer</item>
+ <item>Sequence Pull Consumer</item>
+ <item>Any Pull Consumer</item>
+ <item>Structured Push Supplier</item>
+ <item>Sequence Push Supplier</item>
+ <item>Any Push Supplier</item>
+ <item>Structured Pull Supplier</item>
+ <item>Sequence Pull Supplier</item>
+ <item>Any Pull Supplier</item>
+ </list>
+ <p>The interfaces for these participants are defined in <em>CosNotification.idl</em>
+ and <em>CosNotifyComm.idl</em>.</p>
+ </section>
+
+ <section>
+ <title>Generating a Client Interface</title>
+ <p>We start by creating an interface which inherits from the correct interface, e.g., <em>CosNotifyComm::SequencePushConsumer</em>. Hence,
+ we must also implement all operations defined in the SequencePushConsumer interface. The IDL-file could look like: </p>
+ <code type="c"><![CDATA[
+#ifndef _MYCLIENT_IDL
+#define _MYCLIENT_IDL
+#include <CosNotification.idl>
+#include <CosNotifyComm.idl>
+
+module myClientImpl {
+
+ interface ownInterface:CosNotifyComm::SequencePushConsumer {
+
+ void ownFunctions(in any NeededArguments)
+ raises(Systemexceptions,OwnExceptions);
+
+ };
+};
+
+#endif
+ ]]></code>
+ <p>Run the IDL compiler on this file by calling the <c>ic:gen/1</c> function.
+ This will produce the API named <c>myClientImpl_ownInterface.erl</c>.
+ After generating the API stubs and the server skeletons it is time to
+ implement the servers and if no special options are sent
+ to the IDl compiler the file name is <c>myClientImpl_ownInterface_impl.erl</c>.</p>
+ <p>The callback module must contain the necessary functions inherited from
+ <em>CosNotification.idl</em> and <em>CosNotifyComm.idl</em>.</p>
+ </section>
+
+ <section>
+ <title>How to Run Everything</title>
+ <p>Below is a short transcript on how to run cosNotification. </p>
+ <code type="none">
+
+%% Start Mnesia and Orber
+mnesia:delete_schema([node()]),
+mnesia:create_schema([node()]),
+orber:install([node()]),
+mnesia:start(),
+orber:start(),
+
+%% If cosEvent not installed before it is necessary to do it now.
+cosEventApp:install(),
+
+%% Install cosNotification in the IFR.
+cosNotificationApp:install(30),
+
+%% Register the application specific Client implementations
+%% in the IFR.
+'oe_myClientImpl':'oe_register'(),
+
+%% Start the cosNotification application.
+cosNotificationApp:start(),
+
+%% Start a factory using the default configuration
+ChFac = cosNotificationApp:start_factory(),
+%% ... or use configuration parameters.
+ChFac = cosNotificationApp:start_factory([]),
+
+%% Create a new event channel. Note, if no QoS- anr/or Admin-properties
+%% are supplied (i.e. empty list) the default settings are used.
+{Ch, ChID} = 'CosNotifyChannelAdmin_EventChannelFactory':
+ create_channel(ChFac, DefaultQoS, DefaultAdmin),
+
+%% Retrieve a SupplierAdmin and a Consumer Admin.
+{AdminSupplier, ASID}=
+ 'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch, 'OR_OP'),
+{AdminConsumer, ACID}=
+\011'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP'),
+
+%% Use the corresponding Admin object to get access to wanted Proxies
+
+%% Create a Push Consumer Proxie, i.e., the Client Push Supplier will
+%% push events to this Proxy.
+{StructuredProxyPushConsumer,ID11}= 'CosNotifyChannelAdmin_SupplierAdmin':
+ obtain_notification_push_consumer(AdminSupplier, 'STRUCTURED_EVENT')),
+
+%% Create Push Suppliers Proxies, i.e., the Proxy will push events to the
+%% registered Push Consumers.
+{ProxyPushSupplier,I4D}='CosNotifyChannelAdmin_ConsumerAdmin':
+ obtain_notification_push_supplier(AdminConsumer, 'ANY_EVENT'),
+{StructuredProxyPushSupplier,ID5}='CosNotifyChannelAdmin_ConsumerAdmin':
+ obtain_notification_push_supplier(AdminConsumer, 'STRUCTURED_EVENT'),
+{SequenceProxyPushSupplier,ID6}='CosNotifyChannelAdmin_ConsumerAdmin':
+ obtain_notification_push_supplier(AdminConsumer, 'SEQUENCE_EVENT'),
+
+%% Create application Clients. We can, for example, start the Clients
+%% our selves or look them up in the naming service. This is application
+%% specific.
+SupplierClient = ...
+ConsumerClient1 = ...
+ConsumerClient2 = ...
+ConsumerClient3 = ...
+
+%% Connect each Client to corresponding Proxy.
+'CosNotifyChannelAdmin_StructuredProxyPushConsumer':
+ connect_structured_push_supplier(StructuredProxyPushConsumer, SupplierClient),
+'CosNotifyChannelAdmin_ProxyPushSupplier':
+ connect_any_push_consumer(ProxyPushSupplier, ConsumerClient1),
+'CosNotifyChannelAdmin_StructuredProxyPushSupplier':
+ connect_structured_push_consumer(StructuredProxyPushSupplier, ConsumerClient2),
+'CosNotifyChannelAdmin_SequenceProxyPushSupplier':
+ connect_sequence_push_consumer(SequenceProxyPushSupplier, ConsumerClient3),
+ </code>
+ <p>The example above, exemplifies a notification system where the SupplierClient
+ in some way generates event and pushes them to the proxy. The push supplier
+ proxies will eventually push the events to each ConsumerClient.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/ch_install.xml b/lib/cosNotification/doc/src/ch_install.xml
new file mode 100644
index 0000000000..3463815bc5
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_install.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Installing cosNotification</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev></rev>
+ <file>ch-install.xml</file>
+ </header>
+
+ <section>
+ <title>Installation Process </title>
+ <p>This chapter describes how to install <seealso marker="cosNotificationApp">cosNotificationApp</seealso>
+ in an Erlang Environment.
+ </p>
+
+ <section>
+ <title>Preparation</title>
+ <p>Before starting the installation process for cosNotification,
+ the application Orber must be running.</p>
+ </section>
+
+ <section>
+ <title>Configuration</title>
+ <p>When using the Notification Service the <c>cosNotification</c> application
+ first must be installed using <c>cosNotificationApp:install()</c> or
+ <c>cosNotificationApp:install(Seconds)</c>, followed by <c>cosNotificationApp:start()</c>.</p>
+ <p>Then the <seealso marker="CosNotifyChannelAdmin_EventChannelFactory">Event Channel Factory</seealso>
+ must be started:</p>
+ <list type="bulleted">
+ <item><c>cosNotificationApp:start_global_factory()</c> - starts and returns a reference to a factory using default configuration parameters.
+ This operation should be used for a multi-node Orber.</item>
+ <item><c>cosNotificationApp:start_global_factory(Options)</c> - starts and returns a reference to a factory using given configuration parameters.
+ This operation should be used for a multi-node Orber.</item>
+ <item><c>cosNotificationApp:start_factory()</c> - starts and returns a reference to a factory using default configuration parameters.</item>
+ <item><c>cosNotificationApp:start_factory(Options)</c> - starts and returns a reference to a factory using given configuration parameters.</item>
+ </list>
+ <p>The following options exist:</p>
+ <list type="bulleted">
+ <item><c>{pullInterval, Seconds}</c> - determine how often Proxy Pull
+ Consumers will check for new events with the client application. The
+ default value is 20 seconds.</item>
+ <item><c>{filterOp, OperationType}</c> - determine which type of Administrator
+ objects should be started, i.e., <c>'OR_OP'</c> or <c>'AND_OP'</c>.
+ The default value is <c>'OR_OP'</c>.</item>
+ <item><c>{timeService, TimeServiceObj | 'undefined'}</c> - to be able to use
+ Start and/or Stop QoS this option must be used. See the function <c>start_time_service/2</c>
+ in the <c>cosTime</c> application. The default value is <c>'undefined'</c>.</item>
+ <item><c>{filterOp, OperationType}</c> - determine which type of Administrator
+ objects should be started, i.e., <c>'OR_OP'</c> or <c>'AND_OP'</c>.
+ The default value is <c>'OR_OP'</c>.</item>
+ <item><c>{gcTime, Seconds}</c> - this option determines how often, for example, proxies
+ will garbage collect expired events. The default value is 60.</item>
+ <item><c>{gcLimit, Amount}</c> - determines how many events will be stored before, for
+ example, proxies will garbage collect expired events. The default value is 50. This
+ option is tightly coupled with the QoS property <c>MaxEventsPerConsumer</c>, i.e.,
+ the <c>gcLimit</c> should be less than <c>MaxEventsPerConsumer</c> and greater than 0.</item>
+ </list>
+ <p>It is possible to define a set of global configuration parameters:</p>
+ <table>
+ <row>
+ <cell align="center" valign="middle"><em>Key</em></cell>
+ <cell align="center" valign="middle"><em>Range</em></cell>
+ <cell align="center" valign="middle"><em>Default</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">type_check</cell>
+ <cell align="left" valign="middle">true | false</cell>
+ <cell align="left" valign="middle">true</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">notify</cell>
+ <cell align="left" valign="middle">atom() | false</cell>
+ <cell align="left" valign="middle">false</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">max_events</cell>
+ <cell align="left" valign="middle">integer() > 0</cell>
+ <cell align="left" valign="middle">50</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">interval_events</cell>
+ <cell align="left" valign="middle">integer() > 0</cell>
+ <cell align="left" valign="middle">10000 milliseconds</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">timeout_events</cell>
+ <cell align="left" valign="middle">integer() > interval_events</cell>
+ <cell align="left" valign="middle">3000000 milliseconds</cell>
+ </row>
+ <tcaption>Global Configuration Parameters</tcaption>
+ </table>
+ <p><em>Comments on the table 'Global Configuration Parameters':</em></p>
+ <taglist>
+ <tag><em>type_check</em></tag>
+ <item>Determine if supplied IOR:s shall be type checked, i.e. invoking
+ corba_object:is_a/2, or not.</item>
+ <tag><em>notify</em></tag>
+ <item>The given value shall point to an existing module exporting
+ a function (arity 1) called <em>terminated</em>. This operation
+ is invoked when a proxy terminates and the argument is a list
+ containing <c>{proxy, IOR}</c>, <c>{client, IOR}</c> and
+ <c>{reason, term()}</c>. The return value is ignored.</item>
+ <tag><em>max_events</em></tag>
+ <item>If a supplier proxy has not been able to push events to a
+ consumer and the queue exceeds this limit, then the proxy will
+ terminate. For this option to have any effect, the
+ <c>EventReliability</c> and <c>ConnectionReliability</c> QoS
+ parameters must be set to <c>Persistent</c>. For more information,
+ see also the <seealso marker="ch_QoS">QoS</seealso> chapter.</item>
+ <tag><em>interval_events</em></tag>
+ <item>The same requirements as for <c>max_events</c>. When a supplier
+ proxy detects problems when trying to push events, this parameter
+ determines how often it should try to call the consumer.</item>
+ <tag><em>timeout_events</em></tag>
+ <item>The same requirements as for <c>max_events</c>. If the
+ proxy has not been able to contact the consumer and this
+ time-limit is reached, then the proxy will terminate.</item>
+ </taglist>
+ <p>The Factory is now ready to use. For a more detailed description see
+ <seealso marker="ch_example">Examples</seealso>.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/ch_introduction.xml b/lib/cosNotification/doc/src/ch_introduction.xml
new file mode 100644
index 0000000000..63e4a58bd5
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_introduction.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Introduction to cosNotification</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev></rev>
+ <file>ch_introduction.xml</file>
+ </header>
+
+ <section>
+ <title>Overview</title>
+ <p>The cosNotification application is a Notification Service compliant with the <url href="http://www.omg.org">OMG</url>
+ Notification Service CosNotification.
+ </p>
+
+ <section>
+ <title>Purpose and Dependencies</title>
+ <p><em>cosNotification</em> is dependent on <em>Orber-3.1.7</em> or later,
+ which provides CORBA functionality in an Erlang environment,
+ <em>cosTime-1.0.1</em> or later and IDL-files to be compiled using <em>IC-4.0.4</em> or later.</p>
+ </section>
+
+ <section>
+ <title>Prerequisites</title>
+ <p>To fully understand the concepts presented in the
+ documentation, it is recommended that the user is familiar
+ with distributed programming, CORBA and the Orber application.
+ </p>
+ <p>Recommended reading includes books recommended by the <em>OMG</em>
+ and <em>Open Telecom Platform Documentation Set</em>. It is also
+ helpful to have read <em>Concurrent Programming in Erlang</em>.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/ch_system.xml b/lib/cosNotification/doc/src/ch_system.xml
new file mode 100644
index 0000000000..126bba5f0b
--- /dev/null
+++ b/lib/cosNotification/doc/src/ch_system.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>The Notification Service Components</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-04-13</date>
+ <rev></rev>
+ <file>ch_system.xml</file>
+ </header>
+
+ <section>
+ <title>The Notification Service Components</title>
+ <p>This chapter describes the Notification Service Components and how they
+ interact.</p>
+
+ <section>
+ <title>Components</title>
+ <p>There are seven components in the OMG Notification Service architecture.
+ These are described below: </p>
+ <marker id="notificationFlow"></marker>
+ <image file="notificationFlow.gif">
+ <icaption>
+Figure 1: The Notification Service Components.</icaption>
+ </image>
+ <list type="bulleted">
+ <item><em>Event Channel:</em> acts as a factory for Administrator objects.
+ Allows clients to set Administrative Properties.</item>
+ <item><em>Supplier Administrators:</em> acts as a factory for Proxy Consumers.
+ Administrators are started as <c>'AND_OP'-</c> or <c>'OR_OP'-</c>type,
+ which determines if events must be validated using both the Administrators
+ associated Filter and/or its Proxy children Filters.</item>
+ <item><em>Consumer Administrators:</em> acts in the same way as Supplier Administrators
+ but handle Proxy Suppliers.</item>
+ <item><em>Consumer Proxy:</em> is connected to a client application. Can be
+ started as <c>Pull</c> or <c>Push</c> object. If the proxy is Push style
+ the client application must push events to the Proxy, otherwise the Proxy is
+ supposed to Pull events. The <c>CosNotification::AdminProperties</c> is
+ used to set the pacing interval.</item>
+ <item><em>Supplier Proxy:</em> Acts in a similar way as the Consumer Proxy, but
+ if started as a <c>Push</c> proxy it will push events to the client
+ application.</item>
+ <item><em>Filters:</em> used to filter events. May be associated with Proxies
+ and Administrators.</item>
+ <item><em>Mapping Filters:</em> used to override events Quality of Service
+ settings. Can only be associated with Consumer Administrators and
+ Proxy Suppliers.</item>
+ </list>
+ <p>When a Proxy is started it is set to accept <c>CORBA::Any</c>,
+ <c>CosNotification::StructuredEvent</c> or <c>CosNotification::EventBatch</c>
+ (a sequence of structured events).</p>
+ <p>If a Proxy is supposed to deliver structured events to a client application
+ and receives an <c>CORBA::Any</c> event, the event is converted to a
+ structured event with <c>type_name</c> set to <c>"%ANY"</c> and the
+ event is stored in <c>remainder_of_body</c>.</p>
+ <p>If a Proxy is supposed to deliver <c>CORBA::Any</c> events to a client application
+ and receives a structured event, the event is stored in an Any type. The
+ Any Type Code will be equal to the <c>CosNotification::StructuredEvent</c>
+ Type Code.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/cosNotificationApp.xml b/lib/cosNotification/doc/src/cosNotificationApp.xml
new file mode 100644
index 0000000000..08bac7f810
--- /dev/null
+++ b/lib/cosNotification/doc/src/cosNotificationApp.xml
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotificationApp</title>
+ <prepared>Niclas Eklund</prepared>
+ <responsible>Niclas Eklund</responsible>
+ <docno></docno>
+ <approved>Niclas Eklund</approved>
+ <checked></checked>
+ <date>2000-01-31</date>
+ <rev>PA1</rev>
+ </header>
+ <module>cosNotificationApp</module>
+ <modulesummary>The main module of the cosNotification application.</modulesummary>
+ <description>
+ <p>To get access to the record definitions for the structures use: <br></br>
+<c>-include_lib("cosNotification/include/*.hrl").</c></p>
+ <p>This module contains the functions for starting and stopping the application.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>install() -> Return</name>
+ <fsummary>Install the cosNotification application</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation installs the cosNotification application.</p>
+ </desc>
+ </func>
+ <func>
+ <name>install(Seconds) -> Return</name>
+ <fsummary>Install the cosNotification application</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation installs the cosNotification application using <c>Seconds</c>
+ delay between each block, currently 6, of IFR-registrations. This approach
+ spreads the IFR database access over a period of time to allow other
+ applications to run smother.</p>
+ </desc>
+ </func>
+ <func>
+ <name>install_event() -> Return</name>
+ <fsummary>Install the necessary cosEvent interfaces</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation, which may <em>only</em> be used if it is impossible to
+ upgrade to <em>cosEvent-2.0</em> or later, installs the necessary
+ cosEvent interfaces. If cosEvent-2.0 is available, use
+ <c>cosEventApp:install()</c> instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>install_event(Seconds) -> Return</name>
+ <fsummary>Install the necessary cosEvent interfaces</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation, which may <em>only</em> be used if it is impossible to
+ upgrade to <em>cosEvent-2.0</em> or later, installs the necessary cosEvent
+ interfaces using <c>Seconds</c> delay between each block of
+ IFR-registrations. If cosEvent-2.0 is available, use
+ <c>cosEventApp:install()</c> instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>uninstall() -> Return</name>
+ <fsummary>Uninstall the cosNotification application</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation uninstalls the cosNotification application.</p>
+ </desc>
+ </func>
+ <func>
+ <name>uninstall(Seconds) -> Return</name>
+ <fsummary>Uninstall the cosNotification application</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation uninstalls the cosNotification application using <c>Seconds</c>
+ delay between each block, currently 6, of IFR-unregistrations. This approach
+ spreads the IFR database access over a period of time to allow other
+ applications to run smother.</p>
+ </desc>
+ </func>
+ <func>
+ <name>uninstall_event() -> Return</name>
+ <fsummary>Uninstall the inherited cosEvent interfaces</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation uninstalls the inherited cosEvent interfaces. If cosEvent
+ is in use this function may not be used. This function may only be used if
+ <c>cosNotificationApp:install_event/1/2</c> was used. If not, use
+ <c>cosEventApp:uninstall()</c> instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>uninstall_event(Seconds) -> Return</name>
+ <fsummary>Uninstall the inherited cosEvent interfaces</fsummary>
+ <type>
+ <v>Return = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation uninstalls the inherited cosEvent interfaces, using <c>Seconds</c>
+ delay between each block of IFR-unregistrations. If cosEvent
+ is in use this function may not be used. This function may only be used if
+ <c>cosNotificationApp:install_event/1/2</c> was used. If not, use
+ <c>cosEventApp:uninstall()</c> instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start() -> Return</name>
+ <fsummary>Start the cosNotification application</fsummary>
+ <type>
+ <v>Return = ok | {error, Reason}</v>
+ </type>
+ <desc>
+ <p>This operation starts the cosNotification application.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop() -> Return</name>
+ <fsummary>Stop the cosNotification application</fsummary>
+ <type>
+ <v>Return = ok | {error, Reason}</v>
+ </type>
+ <desc>
+ <p>This operation stops the cosNotification application.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start_global_factory() -> ChannelFactory</name>
+ <fsummary>Start a global channel factory as default</fsummary>
+ <type>
+ <v>ChannelFactory = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a
+ <seealso marker="CosNotifyChannelAdmin_EventChannelFactory">Event Channel Factory</seealso>
+ should be used for a multi-node Orber.
+ The Factory is used to create a new
+ <seealso marker="CosNotifyChannelAdmin_EventChannel">channel</seealso>. </p>
+ </desc>
+ </func>
+ <func>
+ <name>start_global_factory(Options) -> ChannelFactory</name>
+ <fsummary>Start a global channel factory with options</fsummary>
+ <type>
+ <v>Options = [Option]</v>
+ <v>Option = {pullInterval, Seconds} | {filterOp, Op} | {gcTime, Seconds} | {gcLimit, Anount} | {timeService, #objref}</v>
+ <v>ChannelFactory = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a
+ <seealso marker="CosNotifyChannelAdmin_EventChannelFactory">Event Channel Factory</seealso> and
+ should be used for a multi-node Orber.
+ The Factory is used to create a new
+ <seealso marker="CosNotifyChannelAdmin_EventChannel">channel</seealso>. </p>
+ <p></p>
+ <list type="bulleted">
+ <item><c>{pullInterval, Seconds}</c> - determine how often Proxy Pull
+ Consumers will check for new events with the client application. The
+ default value is 20 seconds.</item>
+ <item><c>{filterOp, OperationType}</c> - determine which type of Administrator
+ objects should be started, i.e., <c>'OR_OP'</c> or <c>'AND_OP'</c>.
+ The default value is <c>'OR_OP'</c>.</item>
+ <item><c>{timeService, TimeServiceObj | 'undefined'}</c> - to be able to use
+ Start and/or Stop QoS this option must be used. See the function <c>start_time_service/2</c>
+ in the <c>cosTime</c> application. The default value is <c>'undefined'</c>.</item>
+ <item><c>{filterOp, OperationType}</c> - determine which type of Administrator
+ objects should be started, i.e., <c>'OR_OP'</c> or <c>'AND_OP'</c>.
+ The default value is <c>'OR_OP'</c>.</item>
+ <item><c>{gcTime, Seconds}</c> - this option determines how often, for example, proxies
+ will garbage collect expired events. The default value is 60.</item>
+ <item><c>{gcLimit, Amount}</c> - determines how many events will be stored before, for
+ example, proxies will garbage collect expired events. The default value is 50. This
+ option is tightly coupled with the QoS property <c>MaxEventsPerConsumer</c>, i.e.,
+ the <c>gcLimit</c> should be less than <c>MaxEventsPerConsumer</c> and greater than 0.</item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name>start_factory() -> ChannelFactory</name>
+ <fsummary>Start a channel factory as default</fsummary>
+ <type>
+ <v>ChannelFactory = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a
+ <seealso marker="CosNotifyChannelAdmin_EventChannelFactory">Event Channel Factory</seealso>.
+ The Factory is used to create a new
+ <seealso marker="CosNotifyChannelAdmin_EventChannel">channel</seealso>. </p>
+ </desc>
+ </func>
+ <func>
+ <name>start_factory(Options) -> ChannelFactory</name>
+ <fsummary>Start a channel factory with options</fsummary>
+ <type>
+ <v>Options = [Option]</v>
+ <v>Option = {pullInterval, Seconds} | {filterOp, Op} | {gcTime, Seconds} | {gcLimit, Amount} | {timeService, #objref}</v>
+ <v>ChannelFactory = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a
+ <seealso marker="CosNotifyChannelAdmin_EventChannelFactory">Event Channel Factory</seealso>.
+ The Factory is used to create a new
+ <seealso marker="CosNotifyChannelAdmin_EventChannel">channel</seealso>. </p>
+ </desc>
+ </func>
+ <func>
+ <name>stop_factory(ChannelFactory) -> Reply</name>
+ <fsummary>Terminate the target object</fsummary>
+ <type>
+ <v>ChannelFactory = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation stop the target channel factory.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start_filter_factory() -> FilterFactory</name>
+ <fsummary>Start a filter factory</fsummary>
+ <type>
+ <v>FilterFactory = #objref</v>
+ </type>
+ <desc>
+ <p>This operation creates a
+ <seealso marker="CosNotifyFilter_FilterFactory">Filter Factory</seealso>.
+ The Factory is used to create a new
+ <seealso marker="CosNotifyFilter_Filter">Filter's</seealso> and
+ <seealso marker="CosNotifyFilter_MappingFilter">MappingFilter's</seealso>. </p>
+ </desc>
+ </func>
+ <func>
+ <name>stop_filter_factory(FilterFactory) -> Reply</name>
+ <fsummary>Terminate the target object</fsummary>
+ <type>
+ <v>FilterFactory = #objref</v>
+ <v>Reply = ok | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>This operation stop the target filter factory.</p>
+ </desc>
+ </func>
+ <func>
+ <name>create_structured_event(Domain, Type, Event, VariableHeader, FilterableBody, BodyRemainder) -> Reply</name>
+ <fsummary>Create a structured event</fsummary>
+ <type>
+ <v>Domain = string()</v>
+ <v>Type = string()</v>
+ <v>Event = string()</v>
+ <v>VariableHeader = [CosNotification::Property]</v>
+ <v>FilterableBody = [CosNotification::Property]</v>
+ <v>BodyRemainder = #any data-type</v>
+ <v>Reply = CosNotification::StructuredEvent | {'EXCEPTION', E}</v>
+ </type>
+ <desc>
+ <p>An easy way to create a structured event is to use this function.
+ Simple typechecks are performed and if one of the arguments is not
+ correct a 'BAD_PARAM' exception is thrown.</p>
+ </desc>
+ </func>
+ <func>
+ <name>type_check() -> Reply</name>
+ <fsummary>Return the value of the configuration parameter type_check</fsummary>
+ <type>
+ <v>Reply = true | false</v>
+ </type>
+ <desc>
+ <p>This operation returns the value of the configuration parameter
+ <c>type_check</c>.</p>
+ </desc>
+ </func>
+ </funcs>
+
+</erlref>
+
diff --git a/lib/cosNotification/doc/src/eventstructure.gif b/lib/cosNotification/doc/src/eventstructure.gif
new file mode 100644
index 0000000000..879c96f980
--- /dev/null
+++ b/lib/cosNotification/doc/src/eventstructure.gif
Binary files differ
diff --git a/lib/cosNotification/doc/src/eventstructure.ps b/lib/cosNotification/doc/src/eventstructure.ps
new file mode 100644
index 0000000000..a9ace9a703
--- /dev/null
+++ b/lib/cosNotification/doc/src/eventstructure.ps
@@ -0,0 +1,2462 @@
+%!PS-Adobe-3.0
+%%Creator: (ImageMagick)
+%%Title: (eventstructure.ps)
+%%CreationDate: (Tue Apr 18 13:35:41 2000)
+%%BoundingBox: 131 284 481 508
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 1
+%%Orientation: Portrait
+%%PageOrder: Ascend
+%%Pages: 1
+%%EndComments
+
+%%BeginDefaults
+%%PageOrientation: Portrait
+%%EndDefaults
+
+%%BeginProlog
+%
+% Display a color image. The image is displayed in color on
+% Postscript viewers or printers that support color, otherwise
+% it is displayed as grayscale.
+%
+/buffer 512 string def
+/byte 1 string def
+/color_packet 3 string def
+/pixels 768 string def
+
+/DirectClassPacket
+{
+ %
+ % Get a DirectClass packet.
+ %
+ % Parameters:
+ % red.
+ % green.
+ % blue.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ compression 0 gt
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/DirectClassImage
+{
+ %
+ % Display a DirectClass image.
+ %
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { DirectClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayDirectClassPacket } image
+ } ifelse
+} bind def
+
+/GrayDirectClassPacket
+{
+ %
+ % Get a DirectClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % red
+ % green
+ % blue
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 gt
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/GrayPseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 gt
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ compression 0 gt
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassImage
+{
+ %
+ % Display a PseudoClass image.
+ %
+ % Parameters:
+ % class: 0-PseudoClass or 1-Grayscale.
+ %
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ class 0 gt
+ {
+ currentfile buffer readline pop
+ token pop /depth exch def pop
+ /grays columns 8 add depth sub depth mul 8 idiv string def
+ columns rows depth
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { currentfile grays readhexstring pop } image
+ }
+ {
+ %
+ % Parameters:
+ % colors: number of colors in the colormap.
+ % colormap: red, green, blue color packets.
+ %
+ currentfile buffer readline pop
+ token pop /colors exch def pop
+ /colors colors 3 mul def
+ /colormap colors string def
+ currentfile colormap readhexstring pop pop
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { PseudoClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayPseudoClassPacket } image
+ } ifelse
+ } ifelse
+} bind def
+
+/DisplayImage
+{
+ %
+ % Display a DirectClass or PseudoClass image.
+ %
+ % Parameters:
+ % x & y translation.
+ % x & y scale.
+ % label pointsize.
+ % image label.
+ % image columns & rows.
+ % class: 0-DirectClass or 1-PseudoClass.
+ % compression: 0-RunlengthEncodedCompression or 1-NoCompression.
+ % hex color packets.
+ %
+ gsave
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ x y translate
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ currentfile buffer readline pop
+ token pop /pointsize exch def pop
+ /Helvetica findfont pointsize scalefont setfont
+ x y scale
+ currentfile buffer readline pop
+ token pop /columns exch def
+ token pop /rows exch def pop
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ currentfile buffer readline pop
+ token pop /compression exch def pop
+ class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
+ grestore
+ showpage
+} bind def
+%%EndProlog
+%%Page: 1 1
+%%PageBoundingBox: 131 284 481 508
+%%BeginData:
+DisplayImage
+131 284
+350.000000 224.000000
+12
+350 224
+1
+1
+1
+8
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99553300
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000335599ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff990000000000224444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444422000000000099ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffee00eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd11
+000033aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa33000011dd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa00aaffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff66000044eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee44000066ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffaa00aaffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff770077ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffee000011eeffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee110000eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770077ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff330033ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffbb000066ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff660000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffff33
+0033ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0000
+00eeffffffffffffffffffffffffffffffffffffffffffffffffffffff88000077ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffeebbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77000099ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee000000eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffaa440044aaffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa00ff
+ffffffffffffffffffffffffffffffffffffff22ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffaa440044aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff7777007777ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777007777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff33bb00bb33ffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee44004400ee441155ccffbb22770077440077ff221166ffaa33
+ffbb22660077ffffffffffffbb22660077ff221166ffbb22770077440077ee440044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb00bb33ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00ff00ff00eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+66ccffdd0044ccffcc22ffff00ffee00ffee00ffaaff00ffff00ffff00ffdd00ffffffff
+ffffff00ffdd00ffaaff00ffff00ffee00ffee0077000000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee00ff00ff00eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff0000eeffff00
+ffff00ffff00ffff00ff779900ffff00ffff00ffff00ffffffffffffff00ffff00ff7799
+00ffff00ffff00ffff0044eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ff00ff7777ffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff2277ffff003388ffee33ffff00ffff00ffff0088
+33ff00ffff00ffff00ffff00ffffffffffffff00ffff008833ff00ffff00ffff00ffff00
+6677ffeebbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffff77
+77ff00ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb
+ff00ffbb33ffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffbb22006633b1552222ccff550077cc0077aa008500772277bb00ccbb00dd
+aa00eeffffffffffbb00ddaa008f00772277550077cc0077aa00b1220066ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffff33bbff00ffbb33ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee00ffff00ffff00eeffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffee00ffff00ffff00eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffaa44ffff00ffff44aaffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff000000000077ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffaa44ffff00ffff44aaffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff9999ffff00ffff9999ffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff9999ffff00ff
+ff9999ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+eebbffffffffffffffffffffffffffffffffffffffffffffffeebbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffdd0011000022ffff22ffffffffffffffffffffffffffffaa00ffffffee00ddffff
+aa00eeffffffffffffffffffffffffaa00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff00ffffffaaff
+ffffffffffffffffffffffffffffffffff00ffffffff00ffffffff00ffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffff00ffffbbbbffaa33ff6611775555ee44
+0044ffee44004400ffffffff00ffffffff00ffee440044ff221166ffee44004400ffee44
+004499227777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffff00000000bbffff00ffff8866aaff77000000bb66ccffdd00ffff
+ffff000000000000ff77000000bbaaff00ff66ccffdd00ff77000000bb00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff
+00ffffeeddffff00ffffff00ccff44eeffffff00ffffff00ffffffff00ffffffff00ff44
+eeffffff779900ff00ffffff00ff44eeffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffddffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffffffffffffffff00ffffffffffff00ffff
+88bb33ff6677ffeebb2277ffff00ffffffff00ffffffff00ff6677ffee6433ff00ff2277
+ffff00ff6677ffeebb00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffee22ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffffffffffbb0000bbffffffbb00ccbb66ff004496220066ffbb
+22006633ddffffbb0099eeddaa00ddcc2200669900772277bb22006633ddcc220066aa00
+55ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff440000881177cc448f22661199ffee440044ffffffffffffbb22
+660077ff221166ffbb22770077440077ffee440044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffff22dddd99ff00eeaa22ff77000000bbffffffffffff00ffdd00ffaaff00ffff00
+ffee00ffee00ff77000000bbffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff887799ffff00
+ffff00ff44eeffffffffffffffffff00ffff00ff779900ffff00ffff00ffff00ff44eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffee2288ffff00ffcc44ff6677ffeebbff
+ffffffffff00ffff008833ff00ffff00ffff00ffff00ff6677ffeebbffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff2266ffff77ccffff002222ccffcc220066ffffffffffffbb00ddaa008f
+00772277550077cc0077aa00ddcc220066ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff99ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff7744ccffffff00ffffffff
+ffffffffff000000000077ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff1100eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffccffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffff9999ffff00ffff9999ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa44ffff00ffff44aaffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffee00ffff00ffff00eeffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffff33bbff
+00ffbb33ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7777ff00ff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffddffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffee22ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee00ff00ff00eeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee440044ff4411eeee55df440044ffbb22660077440000ffffff
+ffffffbb22660077ff221166ffbb22770077440077ee440044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb00bb33ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+77000000bbee22ddddaa77000000bbff00ffdd00ff00ffffffffffffffff00ffdd00ffaa
+ff00ffff00ffee00ffee0077000000bbffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777007777ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff44eeffffffff997799ff
+44eeffffffff00ffff00ff00ffffffffffffffff00ffff00ff779900ffff00ffff00ffff
+0044eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffaa440044aaffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff6677ffeebbffee3399ff6677ffeebbff00ffff00
+ff00ffffffffffffffff00ffff008833ff00ffff00ffff00ffff006677ffeebbffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee000000eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffcc220066ffffff66ddffcc220066ffbb00ddaa00ee2266ffffffffffffbb
+00ddaa008f00772277550077cc0077aa00b1220066ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff330033ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff770077ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000077ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffaa00aaffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+bbffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffdd0011000022ffffffffffffffffffffffffffffffffffff
+ddffffffee00ddffffaa00eeffffffffffffffffffffffffffaa00ffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffaaffffffffffffffffffffffffffffffffffee22ffffffff00ffffffff
+00ffffffffffffffffffffffffffffff00ffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffaa00aaffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffddbbff44
+11eeee55df440044ffbb22660077ff440000ffffff00ffffffff00ffee440044ffff2211
+66ffee44004400ee440044ff99227777ffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770077ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00000000bbffee22ddddaa77000000bbff
+00ffdd00ffff00ffffffff000000000000ff77000000bbffaaff00ff66ccffdd00770000
+00bbff00ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffff33
+0033ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffeeddffff997799ff44eeffffffff00ffff00ffff00ffffff
+ff00ffffffff00ff44eeffffffff779900ff00ffffff0044eeffffffff00ffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffeebbffffffffffee2233ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffffffffffeebbffffffffffee2233ffffffffffffffffffffffffffffffffbb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee000000eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffeebbffee3399ff6677ffeebbff00ffff00ffff00ffffffff00ffffffff00ff6677
+ffeebb8833ff00ff2277ffff006677ffeebbff00ffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffaa
+00ffffffffff66ee77ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffaa
+00ffffffffff66ee77ffffffffffffffffffffffffffffffcc00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffaa440044aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffbb0077110000ddffff66ddff
+cc220066ffbb00ddaa00eeff2266ffffbb0099eeddaa00ddcc220066ff9900772277bb22
+006633b1220066ffaa0055ffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffff00ffffffffff11ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffffffffffffff00ffffffffff11ffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777007777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffee441155ccff00660077ff440000bbffffffffffbb22660077ff
+221166ffbb22770077440077ee440044ffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffffee441155ccff00660077ff440000bbffffffffff4411eeee55ee
+221166ffff00ff9900bb0000ee440044ffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb00bb33ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+44ccffcc22ff00eecc00ffff00ffffffffffffffff00ffdd00ffaaff00ffff00ffee00ff
+ee0077000000bbffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+44ccffcc22ff00eecc00ffff00ffffffffffffffee22ddddaaffaaff00ffff00ffff00ff
+ff0077000000bbffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee00ff00ff00eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffff00eeffff00ff00ffff00
+ffff00ffffffffffffffff00ffff00ff779900ffff00ffff00ffff0044eeffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffff00eeffff00ff00ffff00
+ffff00ffffffffffffffff997799ffff779900ffff00ffff00ffff0044eeffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffff3388ffee33ff00ffff00ffff00ffffffffffffff
+ff00ffff008833ff00ffff00ffff00ffff006677ffeebbffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffff3388ffee33ff00ffff00ffff00ffffffffffffff
+ffee3399ff8833ff00ffff00ffff00ffee006677ffeebbffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffff77
+77ff00ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffcc552222ccaa00ddaa00eebb0000ffffffffffffbb00ddaa008f00772277
+550077cc0077aa00b1220066ffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffcc552222ccaa00ddaa00eebb0000ffffffffffffffff66ddff9900772277
+bb00ccff33118844cc220066ffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffff33bbff00ffbb33ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffee00ffff00ffff00eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+000000000077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffff
+000000000077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffaa44ffff00ffff44aaffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff9999ffff00ff
+ff9999ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffeebbffffffffffee2233ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffffffffffeebbffffffffffee2233ffffffffffffffffffffffffffffffffbb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffaa
+00ffffffffff66ee77ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffaa
+00ffffffffff66ee77ffffffffffffffffffffffffffffffcc00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffff00ffffffffff11ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffffffffffffff00ffffffffff11ffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffee441155ccff00660077ff440000bbffffffffffbb22660077ff
+221166ffbb22770077440077ee440044ffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffffee441155ccff00660077ff440000bbffffffffff4411eeee55ee
+221166ffff00ff9900bb0000ee440044ffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+44ccffcc22ff00eecc00ffff00ffffffffffffffff00ffdd00ffaaff00ffff00ffee00ff
+ee0077000000bbffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+44ccffcc22ff00eecc00ffff00ffffffffffffffee22ddddaaffaaff00ffff00ffff00ff
+ff0077000000bbffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffeebbffffffffbbffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffeebbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffff00eeffff00ff00ffff00
+ffff00ffffffffffffffff00ffff00ff779900ffff00ffff00ffff0044eeffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffff00eeffff00ff00ffff00
+ffff00ffffffffffffffff997799ffff779900ffff00ffff00ffff0044eeffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffff4400aaffff9944eeffffffffffffffffff22ff
+ffffffffffaa00ffffffcc00ffffffffffffffffffee00ddffffaa00eeffffffffffffff
+ffffffffffaa00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffff3388ffee33ff00ffff00ffff00ffffffffffffff
+ff00ffff008833ff00ffff00ffff00ffff006677ffeebbffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffff3388ffee33ff00ffff00ffff00ffffffffffffff
+ffee3399ff8833ff00ffff00ffff00ffee006677ffeebbffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffff7766ffffcc99ffffffffffffffffffffffffffffffffffff00ffffff
+ff00ffffffffffffffffffff00ffffffff00ffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffcc552222ccaa00ddaa00eebb0000ffffffffffffbb00ddaa008f00772277
+550077cc0077aa00b1220066ffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffcc552222ccaa00ddaa00eebb0000ffffffffffffffff66ddff9900772277
+bb00ccff33118844cc220066ffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffdd00
+ddff77ffffff221166ff9922775033ffff221166ffff005511aaff00ffee440044ffffff
+ffff00ffffffff00ffee440044ff221166ffee44004400ffee44004499227777ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffffffffff6677ee77ffffffaaff00ff
+ff00ffff00ffffaaff00ffff00eebb22ff00ff77000000bbffffffff000000000000ff77
+000000bbaaff00ff66ccffdd00ff77000000bb00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+000000000077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffff
+000000000077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffffffffdd1188ddffffff779900ffff00ffff00ffff779900
+ffff00ffff00ff00ff44eeffffffffffffff00ffffffff00ff44eeffffff779900ff00ff
+ffff00ff44eeffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ffffffffffff4444ffffff8833ff00ffff00ffff00ff8833ff00ffff00ffee44ff00ff66
+77ffeebbffffffff00ffffffff00ff6677ffee6433ff00ff2277ffff00ff6677ffeebb00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffbb99ffff
+ff9900772277aa0055bb00cc9900772277ff222244ccbb00cccc220066ffffffffbb0099
+eeddaa00ddcc2200669900772277bb22006633ddcc220066aa0055ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffdd22ffdd22dd22ffdd22ffdd
+22ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99
+99ffff00ffff9999ffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffff9999ffff00ffff9999ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffaa44ffff00ffff44aaffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa44ffff00ffff44aaffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee00ffff00ffff00eeffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffee00ffff00ffff00eeffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff33bbff00ffbb33ffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffff33bbff
+00ffbb33ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ff00
+ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffeebbffffffffffee2233ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffffffffffeebbffffffffffee2233ffffffffffffffffffffffffffffffffbb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7777ff00ff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffaa
+00ffffffffff66ee77ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffaa
+00ffffffffff66ee77ffffffffffffffffffffffffffffffcc00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee00ff00ff00eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffff00ffffffffff11ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffffffffffffff00ffffffffff11ffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee00ff00ff00eeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff33bb00bb33ffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffee441155ccff00660077ff440000bbffffffffffbb22660077ff
+221166ffbb22770077440077ee440044ffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffffee441155ccff00660077ff440000bbffffffffff4411eeee55ee
+221166ffff00ff9900bb0000ee440044ffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb00bb33ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777007777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+44ccffcc22ff00eecc00ffff00ffffffffffffffff00ffdd00ffaaff00ffff00ffee00ff
+ee0077000000bbffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+44ccffcc22ff00eecc00ffff00ffffffffffffffee22ddddaaffaaff00ffff00ffff00ff
+ff0077000000bbffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777007777ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffaa440044aaffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffff00eeffff00ff00ffff00
+ffff00ffffffffffffffff00ffff00ff779900ffff00ffff00ffff0044eeffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffff00eeffff00ff00ffff00
+ffff00ffffffffffffffff997799ffff779900ffff00ffff00ffff0044eeffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffaa440044aaffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffee000000eeffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff88000077ffffffffffffff3388ffee33ff00ffff00ffff00ffffffffffffff
+ff00ffff008833ff00ffff00ffff00ffff006677ffeebbffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffff3388ffee33ff00ffff00ffff00ffffffffffffff
+ffee3399ff8833ff00ffff00ffff00ffee006677ffeebbffffffffffffffffffffffffff
+ffffffffff77000099ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee000000eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+330033ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb000066ff
+ffffffffffffcc552222ccaa00ddaa00eebb0000ffffffffffffbb00ddaa008f00772277
+550077cc0077aa00b1220066ffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffcc552222ccaa00ddaa00eebb0000ffffffffffffffff66ddff9900772277
+bb00ccff33118844cc220066ffffffffffffffffffffffffffffffffffffff660000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff330033ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff770077ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee000011eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffee110000eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff770077ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa00aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff66000044eeffffffffffffffffffffffffffffffffffffff
+000000000077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffff
+000000000077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffee44000066ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffaa00aaffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee00eeffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffdd11000033aaffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa33
+000011ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000099ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff9900000000000a1313131313131313131313131313131313131313
+131313131313131313131313131313131313131313131313131313131313131313131313
+131313131313131309091313131313131313131313131313131313131313131313131313
+131313131313131313131313131313131313131313131313131313131313131313131313
+131307000000000099ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffee00eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd11
+000033aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa33000011dd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa00aaffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff66000044eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee44000066ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffaa00aaffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff770077ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffee000011eeffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee110000eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770077ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff330033ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffbb000066ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff660000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffff33
+0033ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0000
+00eeffffffffffffffffffffffffffffffffffffffffffffffffffffff88000077ffffff
+ffffffffffee2233ffffffeebbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffee2233ffffffeebbffffffffffffffffffffffffffffffffffbbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77000099ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee000000eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffaa440044aaffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffff66ee77ffff
+ffaa00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff66ee77ffff
+ffaa00ffffffffffffffffffffffffffffffffcc00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffaa440044aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff7777007777ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffff11ffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffff11ffffffffffff00ffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777007777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff33bb00bb33ffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffff440000bbee44004400ffffffffffbb22660077ffff221166ffbb
+22770077440077ee440044ffffffffffffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffff440000bbee44004400ffffffffff4411eeee55eeff221166ffff
+00ff9900bb0000ee440044ffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb00bb33ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00ff00ff00eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ff00ffff66ccffdd00ffffffffffff00ffdd00ffffaaff00ffff00ffee00ffee00770000
+00bbffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ff00ffff66ccffdd00ffffffffffee22ddddaaffffaaff00ffff00ffff00ffff00770000
+00bbffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee00ff00ff00eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffff00ffff00ffffff00ff
+ffffffffff00ffff00ffff779900ffff00ffff00ffff0044eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffff00ffff00ffffff00ff
+ffffffffff997799ffffff779900ffff00ffff00ffff0044eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ff00ff7777ffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffff00ffff2277ffff00ffffffffffff00ffff00ff
+8833ff00ffff00ffff00ffff006677ffeebbffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffff00ffff2277ffff00ffffffffffffee3399ffff
+8833ff00ffff00ffff00ffee006677ffeebbffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffff77
+77ff00ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb
+ff00ffbb33ffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffbb0000ffbb22006633ddffffffffbb00ddaa00ee9900772277550077cc00
+77aa00b1220066ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffbb0000ffbb22006633ddffffffffffff66ddffff9900772277bb00ccff33
+118844cc220066ffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffff33bbff00ffbb33ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee00ffff00ffff00eeffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffee00ffff00ffff00eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffaa44ffff00ffff44aaffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffff0000000000
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff0000000000
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffaa44ffff00ffff44aaffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff9999ffff00ffff9999ffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff9999ffff00ff
+ff9999ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffee2233ffffffeebbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffee2233ffffffeebbffffffffffffffffffffffffffffffffffbbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffff66ee77ffff
+ffaa00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff66ee77ffff
+ffaa00ffffffffffffffffffffffffffffffffcc00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffff11ffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffff11ffffffffffff00ffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffff440000bbee44004400ffffffffffbb22660077ffff221166ffbb
+22770077440077ee440044ffffffffffffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffff440000bbee44004400ffffffffff4411eeee55eeff221166ffff
+00ff9900bb0000ee440044ffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ff00ffff66ccffdd00ffffffffffff00ffdd00ffffaaff00ffff00ffee00ffee00770000
+00bbffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ff00ffff66ccffdd00ffffffffffee22ddddaaffffaaff00ffff00ffff00ffff00770000
+00bbffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffbbffffffffffffffffffffffffffffffffffeebbffffffffffbbffffffffffffffffff
+ffffffffffffffffffffffffffffffeebbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffff00ffff00ffffff00ff
+ffffffffff00ffff00ffff779900ffff00ffff00ffff0044eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffff00ffff00ffffff00ff
+ffffffffff997799ffffff779900ffff00ffff00ffff0044eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffffdd0011000022ff22ffcc00ffffddffffffffff
+ffffffffffffffffffaa00ffffffffcc00ffffffffffffffff440033002299ffffffffff
+ffffffffffaa00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffff00ffff2277ffff00ffffffffffff00ffff00ff
+8833ff00ffff00ffff00ffff006677ffeebbffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffff00ffff2277ffff00ffffffffffffee3399ffff
+8833ff00ffff00ffff00ffee006677ffeebbffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffff00ffffffaaffffffff00ffee22ffffffffffffffffffffffffffffff
+00ffffffffff00ffffffffffffffffff00ffffbb00ffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffbb0000ffbb22006633ddffffffffbb00ddaa00ee9900772277550077cc00
+77aa00b1220066ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffbb0000ffbb22006633ddffffffffffff66ddffff9900772277bb00ccff33
+118844cc220066ffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff00ff
+ffbbbbaa33ffff00ff440000ee440044ff99227777221166ffff005511aaffff00ffee44
+0044ffffffff00ffffaa33ffee441155ccffee44004400881177cc44eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffffffff00000000bbff00ffff00ffff
+00ff77000000bbff00ffffaaff00ffff00eebb22ffff00ff77000000bbffffff00777722
+99ff44ccffcc22ff66ccffdd00ff22dddd99ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffff0000000000
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff0000000000
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffffff00ffffeeddff00ffff00ffff00ff44eeffffffff00ff
+ff779900ffff00ffff00ffff00ff44eeffffffffffff00ffffee00ff00eeffff00ff00ff
+ffff00ff887799ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ffffffff00ffffffffff00ffff00ffff00ff6677ffeebbff00ff8833ff00ffff00ffee44
+ffff00ff6677ffeebbffffff00ffffee00ff3388ffee33ff2277ffff00ffee2288ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffbb0000bbffffbb
+00ccbb00ccff2266cc220066ffaa00559900772277ff222244ccffbb00cccc220066ffff
+ffbb0033224499ffcc552222ccffbb22006633ddff77ccffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff99ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffeebbffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+44ccffffffffffffffffffffffffffffffffffffffdd0011000022ffffffffffffffffff
+ffffffffffffffffffddffffff440033002299ffffffffffffffffffffaa00ffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffaaffffffffffffffffffffffffffffffffffee22
+ffffffff00ffffbb00ffffffffffffffffffffff00ffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffddbbff4411eeee55df440044ffbb22660077ff440000ffffff00ffffaa33ff
+ffee441155ccee44004400881177cc44eeffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000bbffee22
+ddddaa77000000bbff00ffdd00ffff00ffffffff0077772299ffff44ccffcc2266ccffdd
+00ff22dddd99ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffeeddffff997799ff44eeffffffff00
+ffff00ffff00ffffffff00ffffee00ffff00eeffff0000ffffff00ff887799ffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffeebbffee3399ff6677ffeebbff00ffff00ffff00ffffffff
+00ffffee00ffff3388ffee332277ffff00ffee2288ffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb0077
+110000ddffff66ddffcc220066ffbb00ddaa00eeff2266ffffbb0033224499ffffcc5522
+22ccbb22006633ddff77ccffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7744ccffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffdd22ffdd22dd22ffdd22ffdd
+22ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffff9999ffff00ffff9999ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa44ffff00ffff44aaffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffee00ffff00ffff00eeffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffff33bbff
+00ffbb33ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffee2233ffffffeebbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffee2233ffffffeebbffffffffffffffffffffffffffffffffffbbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7777ff00ff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffff66ee77ffff
+ffaa00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff66ee77ffff
+ffaa00ffffffffffffffffffffffffffffffffcc00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffff11ffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffff11ffffffffffff00ffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee00ff00ff00eeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffff440000bbee44004400ffffffffffbb22660077ffff221166ffbb
+22770077440077ee440044ffffffffffffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffff440000bbee44004400ffffffffff4411eeee55eeff221166ffff
+00ff9900bb0000ee440044ffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff33bb00bb33ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ff00ffff66ccffdd00ffffffffffff00ffdd00ffffaaff00ffff00ffee00ffee00770000
+00bbffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ff00ffff66ccffdd00ffffffffffee22ddddaaffffaaff00ffff00ffff00ffff00770000
+00bbffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777007777ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffff00ffff00ffffff00ff
+ffffffffff00ffff00ffff779900ffff00ffff00ffff0044eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffff00ffff00ffffff00ff
+ffffffffff997799ffffff779900ffff00ffff00ffff0044eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffaa440044aaffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffff00ffff2277ffff00ffffffffffff00ffff00ff
+8833ff00ffff00ffff00ffff006677ffeebbffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffff00ffff2277ffff00ffffffffffffee3399ffff
+8833ff00ffff00ffff00ffee006677ffeebbffffffffffffffffffffffffffffffffffff
+ffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee000000eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffbb0000ffbb22006633ddffffffffbb00ddaa00ee9900772277550077cc00
+77aa00b1220066ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffbb0000ffbb22006633ddffffffffffff66ddffff9900772277bb00ccff33
+118844cc220066ffffffffffffffffffffffffffffffffffffffffffffffff770000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff330033ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff770077ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffff0000000000
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff0000000000
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffaa00aaffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffee00ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff77000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99
+99ffff00ffff9999ffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff770000
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffaa44ffff00ffff44aaffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee00ffff00ffff00eeffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff33bbff00ffbb33ffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff770000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ff00
+ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffeebbffffffffffff
+ffffffffffffffffffffffffffffffee2233ffffffffffeebbffffffffffffffffffffff
+eebbffffffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffeebbffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffaa44ff00ff44aaffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff22ffffffffffffffffffaa00ffffffffffffffffffffffffffffffff
+ffffffffff66ee77ffffffffffaa00ffffffffffffffffffffffaa00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffffffdd0011002299ffffffffffffffffff
+ffffffffffffffffffffff22ffffffffffffffff22ffffffffffffffffffffffffffff44
+0033002299ffffffffffffffffffffaa00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee00ff00ff00eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff11ffffffff
+ffffffff00ffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff770000bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffff00ffffbb00ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffbb00ffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff33bb00bb33ffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff99227777ee440044bb22770077440077ffff221166ffaa33ffbb22660077ee44004400
+ee440044ff99227777ffffffffffee441155ccff440000bbffffffffffff005511aaee44
+1155ccee44004400ff881177cc44eeffffffffffffffffffffffffffffffffffffffff77
+0000bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffff00ffff9933ffee440044ffbb22770077440077ff221166ffaa33ffbb22660077ffaa
+33ffbb22660077ee44114411ffffffff00ffffaa33ffee441155ccffee44004400881177
+cc44eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777007777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff77000000bb
+00ffee00ffee00ffffaaff00ffff00ffff00ffdd0066ccffdd0077000000bbff00ffffff
+ffffffff44ccffcc22ffff00ffffffffffffffff00eebb2244ccffcc2266ccffdd00ffff
+22dddd99ffffffffffffffffffffffffffffffffffffffffff770000bbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffff00773377eeff7700
+0000bbff00ffee00ffee00ffaaff00ffff00ffff00ffdd00ffff00ffff00ffdd007744ff
+33ddffffffff0077772299ff44ccffcc22ff66ccffdd00ff22dddd99ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffaa440044aaffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffff44eeffffff00ffff00ffff00ffff77
+9900ffff00ffff00ffff0000ffffff0044eeffffffff00ffffffffffffff00eeffff00ff
+ff00ffffffffffffffff00ffff0000eeffff0000ffffff00ffff887799ffffffffffffff
+ffffffffffffffffffffffffffffff770000bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffffff00ff7755ffff44eeffffffff00ffff00ffff
+00ff779900ffff00ffff00ffff00ffff00ffff00ffff00aa22ee00ffffffffff00ffffee
+00ff00eeffff00ff00ffffff00ff887799ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffee000000eeffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff88000077ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffff6677ffeebb00ffff00ffff00ff8833ff00ffff00ffff00ffff
+002277ffff006677ffeebbff00ffffffffffffff3388ffee33ffff00ffffffffffffffff
+00ffee443388ffee332277ffff00ffffee2288ffffffffffffffffffffffffffffffffff
+ffffffffff77000099ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffff00ffff3377ff6677ffeebbff00ffff00ffff008833ff00ffff00ffff
+00ffff00ffff00ffff00ffff00ff775599ffffffffff00ffffee00ff3388ffee33ff2277
+ffff00ffee2288ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+330033ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb000066ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa0055
+ffcc220066550077cc0077aa00dd9900772277bb00ccbb00ddaa00af22006633b1220066
+ffaa0055ffffffffffffcc552222ccffbb0000ffffffffffffff222244cccc552222ccbb
+22006633ddffff77ccffffffffffffffffffffffffffffffffffffffffffff660000bbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffbb00aa
+eeee1188cc220066ff550077cc0077aa008500772277bb00ccbb00ddaa00eebb00ccbb00
+ddaa009f224455aaffffffbb0033224499ffcc552222ccffbb22006633ddff77ccffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff770077ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee000011eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99ffff
+ffffffffffffffffffffffffffffffffffffffffee110000eeffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99ddddbb00ffff
+ffffffffffffffffffffffffffffffffffffffffff99ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa00aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff66000044eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000077ffffffffffffffff00
+0000000077ffffffffffffffffffffffffffffffff7744ccffffffffffffffffffffffff
+ffffffffffffffffffee44000066ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff11bbff9977ffffffffffffffffffffffff
+ffffffffffffffffff7744ccffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee00eeffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffdd11000033aaffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa33
+000011ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc221177ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000099ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff995544444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444433445599ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+%%EndData
+%%PageTrailer
+%%Trailer
+%%BoundingBox: 131 284 481 508
+%%EOF
diff --git a/lib/cosNotification/doc/src/fascicules.xml b/lib/cosNotification/doc/src/fascicules.xml
new file mode 100644
index 0000000000..0678195e07
--- /dev/null
+++ b/lib/cosNotification/doc/src/fascicules.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
+
+<fascicules>
+ <fascicule file="part" href="part_frame.html" entry="no">
+ User's Guide
+ </fascicule>
+ <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
+ Reference Manual
+ </fascicule>
+ <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
+ Release Notes
+ </fascicule>
+ <fascicule file="" href="../../../../doc/print.html" entry="no">
+ Off-Print
+ </fascicule>
+</fascicules>
+
diff --git a/lib/cosNotification/doc/src/make.dep b/lib/cosNotification/doc/src/make.dep
new file mode 100644
index 0000000000..031a2b3e98
--- /dev/null
+++ b/lib/cosNotification/doc/src/make.dep
@@ -0,0 +1,48 @@
+# ----------------------------------------------------
+# >>>> Do not edit this file <<<<
+# This file was automaticly generated by
+# /home/otp/bin/docdepend
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# TeX files that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: CosNotification.tex CosNotification_AdminPropertiesAdmin.tex \
+ CosNotification_QoSAdmin.tex CosNotifyChannelAdmin_ConsumerAdmin.tex \
+ CosNotifyChannelAdmin_EventChannel.tex CosNotifyChannelAdmin_EventChannelFactory.tex \
+ CosNotifyChannelAdmin_ProxyConsumer.tex CosNotifyChannelAdmin_ProxyPullConsumer.tex \
+ CosNotifyChannelAdmin_ProxyPullSupplier.tex \
+ CosNotifyChannelAdmin_ProxyPushConsumer.tex \
+ CosNotifyChannelAdmin_ProxyPushSupplier.tex \
+ CosNotifyChannelAdmin_ProxySupplier.tex CosNotifyChannelAdmin_SequenceProxyPullConsumer.tex \
+ CosNotifyChannelAdmin_SequenceProxyPullSupplier.tex \
+ CosNotifyChannelAdmin_SequenceProxyPushConsumer.tex \
+ CosNotifyChannelAdmin_SequenceProxyPushSupplier.tex \
+ CosNotifyChannelAdmin_StructuredProxyPullConsumer.tex \
+ CosNotifyChannelAdmin_StructuredProxyPullSupplier.tex \
+ CosNotifyChannelAdmin_StructuredProxyPushConsumer.tex \
+ CosNotifyChannelAdmin_StructuredProxyPushSupplier.tex \
+ CosNotifyChannelAdmin_SupplierAdmin.tex CosNotifyComm_NotifyPublish.tex \
+ CosNotifyComm_NotifySubscribe.tex CosNotifyFilter_Filter.tex \
+ CosNotifyFilter_FilterAdmin.tex CosNotifyFilter_FilterFactory.tex \
+ CosNotifyFilter_MappingFilter.tex book.tex \
+ ch_BNF.tex ch_QoS.tex ch_contents.tex ch_example.tex \
+ ch_install.tex ch_introduction.tex ch_system.tex \
+ cosNotificationApp.tex part.tex ref_man.tex
+
+# ----------------------------------------------------
+# Source inlined when transforming from source to LaTeX
+# ----------------------------------------------------
+
+book.tex: ref_man.xml
+
+# ----------------------------------------------------
+# Pictures that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: eventstructure.ps
+
+book.dvi: notificationFlow.ps
+
diff --git a/lib/cosNotification/doc/src/notes.gif b/lib/cosNotification/doc/src/notes.gif
new file mode 100644
index 0000000000..e000cca26a
--- /dev/null
+++ b/lib/cosNotification/doc/src/notes.gif
Binary files differ
diff --git a/lib/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml
new file mode 100644
index 0000000000..c66be87c7c
--- /dev/null
+++ b/lib/cosNotification/doc/src/notes.xml
@@ -0,0 +1,391 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotification Release Notes</title>
+ <prepared></prepared>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2000-01-31</date>
+ <rev>A</rev>
+ <file>notes.xml</file>
+ </header>
+
+ <section>
+ <title>cosNotification 1.1.12</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ The documentation is now built with open source tools (xsltproc and fop)
+ that exists on most platforms. One visible change is that the frames are removed.</p>
+ <p>
+ Own Id: OTP-8201 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.11</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Obsolete guards, e.g. record vs is_record, has been changed
+ to avoid compiler warnings.</p>
+ <p>Own id: OTP-7987</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.10</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Updated file headers.</p>
+ <p>Own id: OTP-7837 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.9</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Documentation source included in open source releases.</p>
+ <p>Own id: OTP-7595 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.8</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The CosNotification proxy objects ignored the gcLimit option, instead
+ the gcTime value was used.</p>
+ <p>Own id: OTP-7553 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.7</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Updated file headers.</p>
+ <p>Own id: OTP-7011</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.6</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation source has been converted from SGML to XML.</p>
+ <p>Own id: OTP-6754</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.5</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Minor Makefile changes.</p>
+ <p>Own id: OTP-6701</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.4</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Removed some unused code.</p>
+ <p>Own id: OTP-6527</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.3</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>A user can now define the QoS EventReliability to be
+ Persistent. Note, this is only a lightweight version
+ and events will be lost if a proxy is terminated.</p>
+ <p>Own id: OTP-5923</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.2</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Possible to configure cosNotification not to type check,
+ by invoking corba_object:is_a/2, supplied IOR:s. When
+ a type check fails, the feedback has been improved.</p>
+ <p>Own id: OTP-5823 Aux Id: seq10143</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The app-file contained duplicated modules.</p>
+ <p>Own id: OTP-4976</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The stub/skeleton-files generated by IC have been improved,
+ i.e., depending on the IDL-files, reduced the size of the
+ erl- and beam-files and decreased dependencies off Orber's
+ Interface Repository. It is necessary to re-compile all IDL-files
+ and use COS-applications, including Orber, compiled with
+ IC-4.2.</p>
+ <p>Own id: OTP-4576</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.0.6</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The exception CosNotifyFilter::InvalidValue, raised by the operation
+ CosNotifyFilter::MappingFilter::add_mapping_constraints, did not contain
+ correct data in the body. Hence, it was not possible to pass this
+ exception to another ORB.</p>
+ <p>Own Id: OTP-4412</p>
+ </item>
+ <item>
+ <p>It was not possible to set the QoS property PacingInterval to zero and
+ the default value was not compliant with the OMG specification. The
+ default value for MaximumBatchSize have also been changed du to the
+ same reason.</p>
+ <p>Own Id: OTP-4413, OTP-4414</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <list type="bulleted">
+ <item>
+ <p>The default value, for the QoS properties PacingInterval and MaximumBatchSize,
+ have been changed to zero (i.e. no timeout) and 1 respectively, which is
+ compliant with the OMG specification.</p>
+ <p>Own Id: OTP-4413, OTP-4414</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.0.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>If one tries to set an unavailable/incorrect property or property value, an
+ exception is thrown. In some cases the exception was not correct, which
+ would cause problems if communicating via IIOP.</p>
+ <p>Own Id: OTP-4340</p>
+ </item>
+ <item>
+ <p>When using Filter's, with the QoS OrderPolicy set to FifoOrder,
+ and passing a sequence of structured events, they could be
+ delivered in the wrong order.</p>
+ <p>Own Id: OTP-4272</p>
+ </item>
+ <item>
+ <p>If Filter's where attached to Supplier proxies it could cause
+ the Proxy to terminate.</p>
+ <p>Own Id: OTP-4272</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.0.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>When passing event sequences, the PushSuppliers and PullSuppliers
+ could crash if the objects had Filter objects associated and
+ only a subset of the sequences where approved. </p>
+ <p>Own Id: OTP-4099</p>
+ </item>
+ <item>
+ <p>SupplierAdmin's did not filter any events, even though Filter objects
+ had been attached to the SupplierAdmin.</p>
+ <p>Own Id: OTP-4098</p>
+ </item>
+ <item>
+ <p>If one used the '_get_default_supplier_admin'/1, exported by the
+ CosNotifyChannelAdmin_EventChannel-module, it resulted in a loop
+ which overloaded the channel. This is no longer the case.</p>
+ <p>Own Id: OTP-4086</p>
+ </item>
+ <item>
+ <p>If one used the '_get_default_filter_factory'/1, exported by the
+ CosNotifyChannelAdmin_EventChannel-module, a new instance was created
+ each time. Now fixed.</p>
+ <p>Own Id: OTP-4092</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+ <list type="bulleted">
+ <item>
+ <p>The include paths for <c>CosNotification.idl</c> have been changed.
+ Hence, if you include this file in your own IDL-files you must
+ update your paths to also point to where the cosEvent IDL-files are
+ stored.</p>
+ <p>Own Id: OTP-4093</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.0.3</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>It is now possible to start global channel factories.</p>
+ <p>Own Id: OTP-4078</p>
+ </item>
+ <item>
+ <p>The Orber, version 3.2.5 or later, configuration parameter
+ orber_debug_level can now be used to generate reports when abnormal
+ situations occurs. For more information consult the Orber User's Guide.
+ Note, it is not recommended to use this option for delivered systems
+ since some of the reports is not to be considered as errors.
+ The value of orber_debug_level must be 3, or higher, for reports to
+ be generated.</p>
+ <p>Own Id: OTP-4077, OTP-3962</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>When using the cosEvent API accessing a cosNotification admins
+ the objects returned by the functions obtain_push_supplier,
+ obtain_pull_supplier, obtain_push_consumer and obtain_pull_consumer
+ was not of the correct type. Due to the interface change
+ it is not possible to upgrade during runtime.</p>
+ <p>Own Id: OTP-4079</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosNotification 1.0.2</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>First release of the cosNotification application.</p>
+ <p>Own Id: -</p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/cosNotification/doc/src/notificationFlow.gif b/lib/cosNotification/doc/src/notificationFlow.gif
new file mode 100644
index 0000000000..31d6ee97fb
--- /dev/null
+++ b/lib/cosNotification/doc/src/notificationFlow.gif
Binary files differ
diff --git a/lib/cosNotification/doc/src/notificationFlow.ps b/lib/cosNotification/doc/src/notificationFlow.ps
new file mode 100644
index 0000000000..4215e66d80
--- /dev/null
+++ b/lib/cosNotification/doc/src/notificationFlow.ps
@@ -0,0 +1,4372 @@
+%!PS-Adobe-3.0
+%%Creator: (ImageMagick)
+%%Title: (notificationFlow.ps)
+%%CreationDate: (Tue Apr 18 11:01:08 2000)
+%%BoundingBox: 105 212 506 579
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 1
+%%Orientation: Portrait
+%%PageOrder: Ascend
+%%Pages: 1
+%%EndComments
+
+%%BeginDefaults
+%%PageOrientation: Portrait
+%%EndDefaults
+
+%%BeginProlog
+%
+% Display a color image. The image is displayed in color on
+% Postscript viewers or printers that support color, otherwise
+% it is displayed as grayscale.
+%
+/buffer 512 string def
+/byte 1 string def
+/color_packet 3 string def
+/pixels 768 string def
+
+/DirectClassPacket
+{
+ %
+ % Get a DirectClass packet.
+ %
+ % Parameters:
+ % red.
+ % green.
+ % blue.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ compression 0 gt
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/DirectClassImage
+{
+ %
+ % Display a DirectClass image.
+ %
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { DirectClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayDirectClassPacket } image
+ } ifelse
+} bind def
+
+/GrayDirectClassPacket
+{
+ %
+ % Get a DirectClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % red
+ % green
+ % blue
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 gt
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/GrayPseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 gt
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ compression 0 gt
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassImage
+{
+ %
+ % Display a PseudoClass image.
+ %
+ % Parameters:
+ % class: 0-PseudoClass or 1-Grayscale.
+ %
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ class 0 gt
+ {
+ currentfile buffer readline pop
+ token pop /depth exch def pop
+ /grays columns 8 add depth sub depth mul 8 idiv string def
+ columns rows depth
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { currentfile grays readhexstring pop } image
+ }
+ {
+ %
+ % Parameters:
+ % colors: number of colors in the colormap.
+ % colormap: red, green, blue color packets.
+ %
+ currentfile buffer readline pop
+ token pop /colors exch def pop
+ /colors colors 3 mul def
+ /colormap colors string def
+ currentfile colormap readhexstring pop pop
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { PseudoClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayPseudoClassPacket } image
+ } ifelse
+ } ifelse
+} bind def
+
+/DisplayImage
+{
+ %
+ % Display a DirectClass or PseudoClass image.
+ %
+ % Parameters:
+ % x & y translation.
+ % x & y scale.
+ % label pointsize.
+ % image label.
+ % image columns & rows.
+ % class: 0-DirectClass or 1-PseudoClass.
+ % compression: 0-RunlengthEncodedCompression or 1-NoCompression.
+ % hex color packets.
+ %
+ gsave
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ x y translate
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ currentfile buffer readline pop
+ token pop /pointsize exch def pop
+ /Helvetica findfont pointsize scalefont setfont
+ x y scale
+ currentfile buffer readline pop
+ token pop /columns exch def
+ token pop /rows exch def pop
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ currentfile buffer readline pop
+ token pop /compression exch def pop
+ class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
+ grestore
+ showpage
+} bind def
+%%EndProlog
+%%Page: 1 1
+%%PageBoundingBox: 105 212 506 579
+%%BeginData:
+DisplayImage
+105 212
+401.000000 367.000000
+12
+401 367
+1
+1
+1
+8
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff995511000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000115599ffffffffffffffffffcc2200000022444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444442200000022ccffffffffffffcc110044aaffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffaa440011ccffffffffff220066ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff660022ffffffff990044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff440099ffffff
+5500aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa
+0055ffffff1100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0011ffffff0022ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0033ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+bbaa7777664444667777aabbffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffcc7744002244777777aaaa7777774422004477ccffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee88221166aaeeffffffffffffffffffffffffeeaa66112288eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffdd771166aaffffffffffffffffffffffffffffffffffffffffaa661177dd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff771166ddffffffffffffffffffffffffffffffffffffffffffff
+ffffdd661177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffbb2244ccffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc4422bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff771188ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff881177ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffee4433ccffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc3344eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee3366eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee6633eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff66
+33eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff6633eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff4466ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff6644ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff7733eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffee3377ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffbb11ccffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc11bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff2288ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8822ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7744ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4477
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffdd11ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffcc11ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee11ddffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffdd11eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+8866ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff6688ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff22aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffaa33ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc11ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff11ccffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+6677ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff22bbffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa44ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffeebbffffffffffffffffffffffff
+ffffffffffffffffffffffffffbbffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffaa3300226677aa00ffffffffffffff
+ffffffffffffffffffffffffffffffffffcc00ffffffffffffffffffffffff7777ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff6677ffffffffffffffffffffffaa44ccffffff77ff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+7766ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffff22ddffffffff
+eeff00660077ffff221166bb22660077ffbb22660077ee440044ffff00ffffffffffffff
+ffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffff00
+ffffffffffffff00eecc00ffffaaff00ff00ffdd00ffff00ffdd0077000000bbff00ffff
+ffffffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffffffffff
+ffffffff22bbffffffffffff00ffff00ffff779900ff00ffff00ffff00ffff0044eeffff
+ffff00ffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffff8833eeffffffccff00ffff00ff8833ff00ff00ffff00ffff00ffff
+006677ffeebbff00ffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffaa55330055ccaa00ddaa00ee990077225800ddaa00
+eebb00ddaa00bf220066ffbb00ccffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44aaffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb
+3333bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffbb22ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff22
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffdd551199991155ddffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffee770077eeffffee770077eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff992244ddffffffffffffdd442299ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffbb4422bbffffffffffffffffffffbb2244bbffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc11ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff11ccffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffdd661188ffffffffffffffffffffffffffff881166
+ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff22aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffaa33ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff771166eeffffffffffffffffffffffffff
+ffffffee661177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff8866ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6688ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffaa2244ccffffffffffffffffffff
+ffffffffffffffffffffcc4422aaffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee11ddffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd11eeffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffcc4422aaffffffffffffff
+ffffffffffffffffffffffffffffffffffaa2244ccffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+6677ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0077ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7700ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffdd11ccffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc11ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7744ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff4477ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff22
+88ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff8822ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffbb11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffcc11bbffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7733eeffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee3377ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff4466ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff6644ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffbbffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee3366ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6633eeffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffdd00110000
+22ffff22ffcc00ffffddffffffffffffffffffffffffffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6633
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff
+ff00ffffffaaffffffffff00ffee22ffffffffffffffffffffffffffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffee6633eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff00ffff00ffffbbbbffaa33ffff00ff440000ee4400449922777788331188ff00ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee4433ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffcc3344eeffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff00ffff00000000bbffff00ffff00ffff00ff77000000bb00ffff1188
+ee99ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff771188ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff881177ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff00ffff00ffffeeddffff00ffff00ffff00ff44eeffffff
+00ffffbb4444ccff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffbb2244ccffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffcc4422bbffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff00ffff00ffffffffffff00ffff00ffff00ff
+6677ffeebb00ffff55ee9911ff00ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff771166ddffffffffffffffffff
+ffffffffffffffffffffffffffffffdd661177ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffbb0000bbffffffbb00ccbb
+00ccff2266cc220066aa0055ff11002277ff00ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd771166aaffff
+ffffffffffffffffffffffffffffffffffffaa661177ddffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee88331166aaeeffffffffffffffffffffffffeeaa66113388eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffcc7744002244777777aaaa7777774422004477ccffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffbbaa7777664444667777aabbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7799ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0077ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff7700ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffcc4422aaffffffffffffffffffffffffffffff
+ffffffffffffffffffaa2244ccffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffaa2244ccffffffffffffffff
+ffffffffffffffffffffffffcc4422aaffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff771166eeff
+ffffffffffffffffffffffffffffffee661177ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffdd661188ffffffffffffffffffffffffffff881166ddffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffbb4422bbffffffffffffffffffffbb2244bbffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff992244ddffffffffffffdd442299ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee770077eeffffee770077eeffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd551199991155dd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb
+3333bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+bbaa7777664444667777aabbffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+bbaa7777664444667777aabbffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffcc7744002244777777aaaa7777774422004477ccffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffcc7744002244777777aaaa7777774422004477ccffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee88221166aaeeffffffffffffffffffffffffeeaa66112288eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0040ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee88221166aaeeffffffffffffffffffffffffeeaa66112288eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffdd771166aaffffffffffffffffffffffffffffffffffffffffaa661177dd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee000eeeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffdd771166aaffffffffffffffffffffffffffffffffffffffffaa661177dd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff771166ddffffffffffffffffffffffffffffffffffffffffffff
+ffffdd661177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee33000033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff771166ddffffffffffffffffffffffffffffffffffffffffffff
+ffffdd661177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffbb2244ccffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc4422bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffbb2244ccffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc4422bbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff771188ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff881177ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff771188ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff881177ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffee4433ccffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc3344eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffee4433ccffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc3344eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee3366eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee6633eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee3366eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee6633eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff66
+33eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff66
+33eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff6633eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff6633eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff4466ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff6644ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff4466ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff6644ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff7733eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffee3377ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff7733eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffee3377ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffbb11ccffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc11bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffbb11ccffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc11bbffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff2288ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8822ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff2288ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8822ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7744ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4477
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7744ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4477
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffdd11ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffcc11ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffdd11ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffcc11ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee11ddffff
+ffffffffffffffffffffeeffffffffffffffffffffffffffffffffffffbbffffffffffff
+ffffffffffffffffffffffffffffdd11eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee11ddffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffdd11eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+8866ffffffffffffffffffff33116644ffffffffffffffffffffffffffffffffffcc00ff
+ff22ffffffffffffffffffffffffffffffffffff6688ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+8866ffffffffffaa3300226677ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff6688ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff22aaffffffffffffffffffff00eeff99ffffffffffffffffffffffffffffff
+ffffff00ffffffffffffffffffffffffffffffffffffffffffaa33ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff22aaffffffffaa44ccffffff77ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffaa33ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc11ffffffffffffffffffffff4455eeffff9900bb000099226611
+99ff9922661199ff00ffaa33ffee440044ff99227777ffffffffffffffffff11ccffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffcc11ffffffffff22ddffffffffeeffee441155ccbb22660077ff88
+3311889900bb0000bb22770077440077ffee44004499227777ffffffffffff11ccffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7766ffffffffffffffffffffffee5511ccffff00ffff
+00ff00eeaa22ffff00eeaa22ff00ffff00ff77000000bbff00ffffffffffffffffffffff
+6677ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7766ffffffffff00ffffffffffffff44ccffcc22ff00
+ffdd00ff1188ee99ff00ffff00ff00ffee00ffee00ff77000000bb00ffffffffffffffff
+6677ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffeeffff9922
+ffff00ffff00ff00ffff00ffff00ffff00ff00ffff00ff44eeffffffff00ffffffffffff
+ffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff44aaffffffffff22bbffffffffffff00ee
+ffff00ff00ffff00ffbb4444ccff00ffff00ff00ffff00ffff00ff44eeffffff00ffffff
+ffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00eeffffffffffffffffffff
+7788ffff00ffff00ffee00ff00ffcc44ffff00ffcc44ff00ffff00ff6677ffeebbff00ff
+ffffffffffffffffffffee00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff00eeffffffffff8833eeffff
+ffccff3388ffee33ff00ffff00ff55ee9911ff00ffee00ff00ffff00ffff00ff6677ffee
+bb00ffffffffffffffffee00ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22ffffffffffff
+ffffffffffbb22000099ffff33118844ff002222ccffff002222ccbb00ccbb00cccc2200
+66ffaa0055ffffffffffffffffffffff22bbffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22ffffffffffff
+ffaa55330055ccffcc552222ccbb00ddaa00ee11002277ff33118844550077cc0077aa00
+ddcc220066aa0055ffffffffffffffff22bbffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa44ff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa44ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffff1100eeffff
+ff1100eeffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffff
+ffffccffffffffffccffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7766ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7766ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffeebbffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffeebbffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffffffffffffff77ccffffffffffffaa00ffffffffff
+ffffffffff22ffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffffffffffffff77ccffffffffffffaa00ffffffffff
+ffffffffff22ffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffaa44ffffffffffffffffffffffffffffffffffff6666ffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44aaffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffaa44ffffffffffffffffffffffffffffffffffff6666ffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44aaffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffbb22ffffffffffffffffffffffffffffffffffaaee22ddffff
+ee44004400ffbb22770077440077aa33ffbb22660077ffffffffffffffffffffffffff22
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffbb22ffffffffffffffffffffffffffffffffffaaee22ddffff
+ee44004400ffbb22770077440077aa33ffbb22660077ffffffffffffffffffffffffff22
+bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00eeffffffffffffffffffffffffffffffff99
+ff9966ffff66ccffdd00ffff00ffee00ffee00ff00ffff00ffdd00ffffffffffffffffff
+ffffffee00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00eeffffffffffffffffffffffffffffffff99
+ff9966ffff66ccffdd00ffff00ffee00ffee00ff00ffff00ffdd00ffffffffffffffffff
+ffffffee00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffff
+ffffffbb00000011eeff00ffffff00ffff00ffff00ffff00ff00ffff00ffff00ffffffff
+ffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff44aaffffffffffffffffffffffff
+ffffffbb00000011eeff00ffffff00ffff00ffff00ffff00ff00ffff00ffff00ffffffff
+ffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffffffffffffff
+ffffffffffffffff66ffffff4477ff2277ffff00ffff00ffff00ffff00ff00ffff00ffff
+00ffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffffffffffffff
+ffffffffffffffff66ffffff4477ff2277ffff00ffff00ffff00ffff00ff00ffff00ffff
+00ffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc11ffff
+ffffffffffffffffffffffffaa33ccffbb3311ddbb22006633dd550077cc0077aa00a300
+ccbb00ddaa00eeffffffffffffffffffffff11ccffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc11ffff
+ffffffffffffffffffffffffaa33ccffbb3311ddbb22006633dd550077cc0077aa00a300
+ccbb00ddaa00eeffffffffffffffffffffff11ccffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff22aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffaa33ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff22aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffaa33ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff8866ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6688ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff8866ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6688ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee11ddffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd11eeffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee11ddffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd11eeffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+6677ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+6677ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffdd11ccffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc11ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffdd11ccffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc11ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7744ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff4477ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7744ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff4477ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff22
+88ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff8822ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff22
+88ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff8822ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffbb11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffcc7b11bbffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffbb11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffcc11bbffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7733eeffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffee100048ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7733eeffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee3377ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff4466ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff3e000099ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff4466ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff6644ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee3366ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff66338f000099
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee3366ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6633eeffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6633
+eeff99000099ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffeeee3366ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6633
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffee6633eeffffff99000099ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3366ee3366
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffee6633eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee4433ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffcc3344eeffffffffff99000099ffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee33
+0033eeee4433ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffcc3344eeffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff771188ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff881177ffffffffffffffff99000099ffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffee330033eeffffff771188ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff881177ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffbb2244ccffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffcc4422bbffffffffffffffffffff99000099ffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffbb2244ccffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffcc4422bbffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff771166ddffffffffffffffffff
+ffffffffffffffffffffffffffffffdd661177ffffffffffffffffffffffffff99000099
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffee330033eeffffffffffffffff771166ddffffffffffffffffff
+ffffffffffffffffffffffffffffffdd661177ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd771166aaffff
+ffffffffffffffffffffffffffffffffffffaa661177ddffffffffffffffffffffffffff
+ffff99000099ffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffee330033eeffffffffffffffffffffdd771166aaffff
+ffffffffffffffffffffffffffffffffffffaa661177ddffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee88331166aaeeffffffffffffffffffffffffeeaa66113388eeffffffffffffffffffff
+ffffffffffffffff99000099ffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ee88331166aaeeffffffffffffffffffffffffeeaa66113388eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffcc7744002244777777aaaa7777774422004477ccffffffffffffffff
+ffffffffffffffffffffffffffff99000099ffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffff
+ffffffffffffffffcc7744002244777777aaaa7777774422004477ccffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffbbaa7777664444667777aabbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff99000099ffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffee330033eeffffffffff
+ffffffffffffffffffffffffffffffffffbbaa7777664444667777aabbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff99000099ffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99000099
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffee33
+0033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff99000099ffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff99000099ffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff990000ccffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7700bbee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffee330033eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff7700af330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7700260033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033df330033eeffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff70
+000033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee33000b0033eeffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffbb3333bbffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee26002deeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee33000bdfff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffdd551199991155ddffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee770077eeffffee770077eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff992244ddffffffffff
+ffdd442299ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb4422bbffff
+ffffffffffffffffbb2244bbffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd6611
+88ffffffffffffffffffffffffffff881166ddffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff771166eeffffffffffffffffffffffffffffffffee661177ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffaa2244ccffffffffffffffffffffffffffffffffffffffffcc4422aaffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffcc4422aaffffffffffffffffffffffffffffffffffffffffffffffffaa
+2244ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0077ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff7700ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffbbffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00ffdd0011000022ffff22ffcc00ffffddffffffffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffff00ffffffaaffffffffff00ffee22ffffff
+ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffff00ffffbbbbffaa33ffff00ff
+440000ee4400449922777788331188ff00ffffffffffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff00000000bbffff
+00ffff00ffff00ff77000000bb00ffff1188ee99ff00ffffffffffffffffffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff00ff
+ffeeddffff00ffff00ffff00ff44eeffffff00ffffbb4444ccff00ffffffffffffffffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffff00ffffffffffff00ffff00ffff00ff6677ffeebb00ffff55ee9911ff00ffffffff
+ffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffbb0000bbffffffbb00ccbb00ccff2266cc220066aa0055ff11002277ff
+00ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff00ffffffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff00ffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0077ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7700ffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc
+4422aaffffffffffffffffffffffffffffffffffffffffffffffffaa2244ccffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffaa2244ccffffffffffffffffffffffffffffffffffffffffcc4422aaffff
+ffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff771166eeffffffffffffffffffffffffffffffffee6611
+77ffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffdd661188ffffffffffffffffffffffffff
+ff881166ddffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffbb4422bbffffffffffff
+ffffffffbb2244bbffffffffffffffffffffffffffffffee330033eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff992244
+ddffffffffffffdd442299ffffffffffffffffffffffffffffffffee330033eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee770077eeffffee770077eeffffffffffffffffffffffffffffffffee330033ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330033eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffdd551199991155ddffffffffffffffffffffffffffffffffffee
+330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee330033eeffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffbb3333bbffffffffffffffffffffffffffffff
+ffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee330033eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffbbaa7777664444667777aabbffffffffffff
+ffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ee330033eeffffffffffffffffffffffffffbbaa7777664444667777aabbffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffcc7744002244777777aaaa777777442200
+4477ccffffffffffffffffee330033eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee330033eeffffffffffffffffcc7744002244777777aaaa777777442200
+4477ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee88221166aaeeffffffffffffffff
+ffffffffeeaa66112288eeffffffffee330033eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffee330033eeffffffffee88221166aaeeffffffffffffffff
+ffffffffeeaa66112288eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffdd771166aaffffffffffffff
+ffffffffffffffffffffffffffaa661177ddffff770033eeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee330000000000381166aaffffffffffffff
+ffffffffffffffffffffffffffaa661177ddffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff771166ddffffffff
+ffffffffffffffffffffffffffffffffffffffffdd661177ffff77eeffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffee55444420053eddffffffff
+ffffffffffffffffffffffffffffffffffffffffdd661177ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb2244ccff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffcc4422bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb2244ccff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffcc4422bbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+1188ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8811
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+1188ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8811
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffee4433ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc3344eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffee4433ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc3344eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee3366eeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee6633eeffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffee3366eeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee6633eeffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee3366ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff6633eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffee3366ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff6633eeffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffee3366ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff6633eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffee3366ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff6633eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff4466ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6644ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff4466ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6644ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7733eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee33
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7733eeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee33
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffbb11ccffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc11bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffbb11ccffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffcc11bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2288ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff8822ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2288ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff8822ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7744ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff4477ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7744ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff4477ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffdd11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffcc11ddffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffdd11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffcc11ddffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff7766ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff7766ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffee11ddffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd11eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffee11ddffffffffffffffffffffffffeeffffffffffffff
+ffffffffffffffffffffffbbffffffffffffffffffffffffffffffffffffffffdd11eeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff8866ffffffffffaa3300226677ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff6688ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff8866ffffffffffffffffffff33116644ffff
+ffffffffffffffffffffffffffffffcc00ffff22ffffffffffffffffffffffffffffffff
+ffff6688ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff22aaffffffffaa44ccffffff77
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffaa33ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff22aaffffffffffffffffffff00
+eeff99ffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff
+ffffffffffffffaa33ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffcc11ffffffffff22dd
+ffffffffeeffee441155ccbb22660077ff883311889900bb0000bb22770077440077ffee
+44004499227777ffffffffffff11ccffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffcc11ffffffffffffff
+ffffffff4455eeffff9900bb00009922661199ff9922661199ff00ffaa33ffee440044ff
+99227777ffffffffffffffffff11ccffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffff
+ffffff00ffffffffffffff44ccffcc22ff00ffdd00ff1188ee99ff00ffff00ff00ffee00
+ffee00ff77000000bb00ffffffffffffffff6677ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ffff
+ffffffffffffffffffee5511ccffff00ffff00ff00eeaa22ffff00eeaa22ff00ffff00ff
+77000000bbff00ffffffffffffffffffffff6677ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff44aaffffffffff22bbffffffffffff00eeffff00ff00ffff00ffbb4444ccff00ffff00
+ff00ffff00ffff00ff44eeffffff00ffffffffffffffffaa44ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff44aaffffffffffffffffffffeeffff9922ffff00ffff00ff00ffff00ffff00ffff00ff
+00ffff00ff44eeffffffff00ffffffffffffffffffffffaa44ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00eeffffffffff8833eeffffffccff3388ffee33ff00ffff00ff55ee9911
+ff00ffee00ff00ffff00ffff00ff6677ffeebb00ffffffffffffffffee00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00eeffffffffffffffffffff7788ffff00ffff00ffee00ff00ffcc44ffff
+00ffcc44ff00ffff00ff6677ffeebbff00ffffffffffffffffffffffee00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffbb22ffffffffffffffaa55330055ccffcc552222ccbb00ddaa00
+ee11002277ff33118844550077cc0077aa00ddcc220066aa0055ffffffffffffffff22bb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffbb22ffffffffffffffffffffffbb22000099ffff33118844ff00
+2222ccffff002222ccbb00ccbb00cccc220066ffaa0055ffffffffffffffffffffff22bb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff44aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffaa44ffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff44aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffff00ffffffffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffff1100eeffffff1100eeffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6677ffffffff
+ffffffffffffffffffffffffffffffffffffffffccffffffffffccffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7766ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44
+aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffaa44ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff44
+aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffaa44ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff44aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa44ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff44aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa44ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff6677ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7766ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffdd001100
+33aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffff
+dd00110033aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffff
+ffff00ffffaa11ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffaa44ffffffffffffffffffff
+ffffffffffff00ffffaa11ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff44aaffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffaa44ffffffffffffffffffff
+ffffffffffffff00ffffbb3399227777ee441155cc6611775555ff881177cc44eeffffff
+ffffffffffffffffffffffff44aaffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22ffffffffff
+ffffffffffffffffffffff00ffffbb3399227770441155ccff6611775555881177cc44ee
+ffffffffffffffffffffffffffffffffff22bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22ffffffffff
+ffffffffffffffffffffffff00660055eeff00ffff44ccffcc22ff8866aaffffff22dddd
+99ffffffffffffffffffffffffffffffff22bbffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+eeffffffffffffffffffffffffffffff00660055eeff00ff44ccffcc22ffff8866aaffff
+22dddd99ffffffffffffffffffffffffffffffffffee00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+eeffffffffffffffffffffffffffffffff00ffffffffff00ffff00eeffff00ffff00ccff
+ffff887799ffffffffffffffffffffffffffffffffee00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff44aaffffffffffffffffffffffffffffff00ffffffffff00ff00eeffff00ffff
+ff00ccffff887799ffffffffffffffffffffffffffffffffffffaa44ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff44aaffffffffffffffffffffffffffffffff00ffffffffff00ffff3388ffee33
+ff88bb33ffffffee2288ffffffffffffffffffffffffffffffffaa44ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff7766ffffffffffffffffffffffffffffff00ffffffffff00ff3388
+ffee33ffff88bb33ffffee2288ffffffffffffffffffffffffffffffffffff6677ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff7766ffffffffffffffffffffffffffffffbb0000bbffffaa0055ff
+cc552222ccbb66ff0044bbffff77ccffffffffffffffffffffffffffffffff6677ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffcc11ffffffffffffffffffffffffffffbb0000bbffff
+aa0055cc552222ccffbb66ff0044bbff77ccffffffffffffffffffffffffffffffffffff
+11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffcc11ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff99ffffffffffffffffffffffffffffffffff
+11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff22aaffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff99ffffffffffffffffffffffffffff
+ffffffffaa33ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff22aaffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff7744ccffffffffffffffffffffffff
+ffffffffaa33ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff8866ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7744ccffffffffffffffffff
+ffffffffffffffffff6688ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff8866ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff6688ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee11ddffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffdd11eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee11ddffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffdd11eeffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7766ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7766ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff6677ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffdd11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc11ddffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffdd11ccffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffcc11ddffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff7744ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff4477ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff7744ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff4477ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff2288ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8822ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff2288ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8822ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffbb11ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc
+11bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffbb11ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc
+11bbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7733eeffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee3377ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7733eeffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee3377ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4466
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff6644ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4466
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff6644ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee3366ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff6633eeffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffee3366ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff6633eeffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffee3366ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff6633eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffee3366ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff6633eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee3366eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee6633eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffee3366eeffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffee6633eeffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee4433ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffcc3344eeffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffee4433ccffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffcc3344eeffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff771188ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff881177ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff771188ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff881177ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22
+44ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc4422bbffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb22
+44ccffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc4422bbffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff771166ddffffffffffffffffffffffffffffffffffffffffffffffffdd6611
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff771166ddffffffffffffffffffffffffffffffffffffffffffffffffdd6611
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffdd771166aaffffffffffffffffffffffffffffffffffffffff
+aa661177ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffdd771166aaffffffffffffffffffffffffffffffffffffffff
+aa661177ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee88331166aaeeffffffffffffffffffffff
+ffeeaa66113388eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffee88331166aaeeffffffffffffffffffffff
+ffeeaa66113388eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+44ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffcc7744002244777777aa
+aa7777774422004477ccffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffcc7744002244777777aa
+aa7777774422004477ccffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+44ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb
+aa7777664444667777aabbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb
+aa7777664444667777aabbffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffa3a3ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffa3a3ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff4850ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff4850ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff3838ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff3838ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff1818ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff1818ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0000eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0000eeffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa0000
+aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa0000
+aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044
+ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff77000077ffffffffffffffffffffffffffffffffffffffffffffffeebbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff77000077ffffffffffffffffffffffffffffffffffffffbbffffbbffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff33000033ffffffffffffffdd00110033aaffffffffffffffffffffaa00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff33000033ffffffffffffffdd00110033aaffffffffffcc00ffcc00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee00080800eeffffffffffffff00ffffaa11ffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffee00080800eeffffffffffffff00ffffaa11ffffffffffff00
+ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa00282800aaffffffffffffff00ffffbb339900
+bb000088331188ffff00660077ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffaa00282800aaffffffffffffff00ffffbb339900
+bb0000ff00ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770040400077ffffffffffffff0066
+0055eeff00ffff001188ee99ffff00eecc00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff770040400077ffffffffffffff0066
+0055eeff00ffff00ff00ffff00ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff330060600033ffffffff
+ffffff00ffffffffff00ffff00bb4444ccffff00ffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff330060600033ffffffff
+ffffff00ffffffffff00ffff00ff00ffff00ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0011777711
+00eeffffffffffff00ffffffffff00ffee0055ee9911ffff00ffff00ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee0011777711
+00eeffffffffffff00ffffffffff00ffee00ff00ffff00ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ff
+ffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa
+005577775500aaffffffffffbb0000bbffffff3311884411002277ffaa00ddaa00eeffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa
+005577775500aaffffffffffbb0000bbffffff33118844bb00ccbb00ccffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7700887777880077ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7700887777880077ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffddee7777eeddffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffddee7777eeddffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffff
+ff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff
+0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff0044ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0044ffffff00
+22ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77
+77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+33ffffff1100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff0011ffffff5500aaffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffaa0055ffffff990044ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff440099ffffffff220066ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff660022ffffffffffcc110044aaffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffaa440011ccffffffffffffcc22000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000022ccffffffffffffff
+ffff99551133444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444442020
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444442020
+444444444444444444444444444444444444444444444444444444444444444444444444
+4444444444444444444444444444444444444444444444444444444433115599ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffbbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffdd0011000022ffffffffffffffffffffffffffffffffffddff
+ffffffdd0011000022cc00ffffffffffffffffffffffffffffffffffee0011337777ffff
+ff22ffffffffffffffffffffffffffffffddffff22ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffaaffffffffffffffffffffffffffff
+ffffee22ffffffffff00ffffffaaff00ffffffffffffffffffffffffffffffffffff00ff
+ffff8877ffffffffffffffffffffffffffffffffffee22ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff00ffffddbbff4411eeee55df4400
+44ffbb22660077440000ffffffff00ffffbbbbff00ffee441155cc8833dd5555ff77bbff
+ffffff00ffffffee11ffaa33ff99227770440044ffee771155ee440000aa33ffee441155
+ccbb22660077ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000bbffee22dd
+ddaa77000000bbff00ffdd00ff00ffffffffff00000000bbff00ff44ccffcc22ee22ffaa
+66ff88ffffffffff00ffffffff00ffff00ffff00ff77000000bb77ccffaaddff00ffff00
+ff44ccffcc22ff00ffdd00ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffee
+ddffff997799ff44eeffffffff00ffff00ff00ffffffffff00ffffeeddff00ff00eeffff
+00ff66aa7722ddaaffffffffff00ffffffee00ffff00ffff00ff44eeffffff00ffffffff
+ff00ffff00ff00eeffff00ff00ffff00ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffeebbffee3399ff6677ffeebbff00ffff00ff00ffffffffff00ffffffffff00
+ff3388ffee33ffcc44998855eeffffffffff00ffffff7755ffff00ffff00ff6677ffeebb
+2266ffeeccff00ffff00ff3388ffee33ff00ffff00ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffff7777ffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb66bb7777bb66bb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffbb0077110000ddffff66ddffcc220066ffbb00ddaa00ee2266ffffffbb0000
+bbffffbb00cccc552222ccffff55ffee66ffffffffffbb0022116677eeffbb00ccaa0055
+cc220066ffcc220077ffff2266bb00cccc552222ccbb00ddaa00eeffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffbb66bb7777bb66bb
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff880077
+7777770088ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff880077
+7777770088ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffcc003377773300ccffffffffffffffffffffffffffffffffffbbffffbbffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffff77aaeeffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffcc003377773300ccffffffffffffffffffffffffffffffffffffffffffeebbffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff110070700011ffffffffffffdd00110033aaffffffffffcc00ffcc00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffdd0000003377aaeeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff110070700011ffffffffffffdd00110033aaffffffffffffffffffff
+aa00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff550050500055ffffffffffffff00ffffaa11ffffffffff
+ff00ffff00ffffffffffffffffffffffffffffffffffffffff4444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444440251705
+000000000e202e4044444499ffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff550050500055ffffffffffffff00ffffaa11ffffffffff
+ffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff880038380088ffffffffffffff00ffffbb33
+9900bb0000ff00ffff00ffffffffffffffffffffffffffffffffffffffff000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000070ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffff880038380088ffffffffffffff00ffffbb33
+9900bb000088331188ffff00660077ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffcc00181800ccffffffffffffff
+00660055eeff00ffff00ff00ffff00ffffffffffffffffffffffffffffffffffffffff00
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000070ffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffcc00181800ccffffffffffffff
+00660055eeff00ffff001188ee99ffff00eecc00ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff11000011ffffff
+ffffffffff00ffffffffff00ffff00ff00ffff00ffffffffffffffffffffffffffffffff
+ffffffff4444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444444444444444444444444444444444444444444444444444444
+444444444444444444444440251705000000000e202e4044444499ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff11000011ffffff
+ffffffffff00ffffffffff00ffff00bb4444ccffff00ffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5500
+0055ffffffffffffffff00ffffffffff00ffee00ff00ffff00ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffdd0000003377aaeeffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5500
+0055ffffffffffffffff00ffffffffff00ffee0055ee9911ffff00ffff00ffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff88000088ffffffffffffffbb0000bbffffff33118844bb00ccbb00ccffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffff77aaeeffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff88000088ffffffffffffffbb0000bbffffff3311884411002277ffaa00ddaa00ee
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffcc0000ccffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffcc0000ccffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0808ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffff0808ffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff2828ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff2828ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff4040ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffff4040ffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6060ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6060ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd00110000
+22ffffffffffffffffffffffffffffffffffffddffffff4400bbffffffffffffffffffff
+ffffffffffffffffddffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffdd0011000022ffffff
+ffffffffffffffffffffffffffffddffffffffffbb77117766ccffffffffffffffddffff
+ffffffffffffffffffffffddffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffaaffffffffffffffffffffffffffffffffffee22ffffffff00ffffffffffff
+ffffffffffffffffffffffffee22ffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff
+ffaaffffffffffffffffffffffffffffffffee22ffffffffaa55ffffffcc44ffffffffff
+ffee22ffffffffffffffffffffffffee22ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff00ffffddbbff4411eeee55df440044ffbb22660077ff440000ffffff00ff
+ffbb226600779922661199ff9900bb0000440000ffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffff00ffffddbbff4411eeee55df440044ffbb22660077440000ffffff22ddffffffff00
+ff9900bb000044000099226611999900bb0000ff440000ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff00000000bbffee22ddddaa77000000bbff00ffdd00ffff00ff
+ffffff00ffffff00ffdd00ff00eeaa22ffff00ffff00ff00ffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff00000000bbffee22ddddaa77000000bbff00ffdd00ff00ffffffff00ff
+ffffffff00ffff00ffff00ff00ffff00eeaa22ff00ffff00ffff00ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff00ffffeeddffff997799ff44eeffffffff00ffff
+00ffff00ffffffff00ffffff00ffff00ff00ffff00ffff00ffff00ff00ffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffff00ffffeeddffff997799ff44eeffffffff00ffff00ff00ff
+ffffff22bbffffffee22ffff00ffff00ff00ffff00ffff00ff00ffff00ffff00ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff00ffffffeebbffee3399ff6677ffee
+bbff00ffff00ffff00ffffffff00ffffff00ffff00ff00ffcc44ffff00ffee00ff00ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff00ffffffeebbffee3399ff6677ffeebbff00ff
+ff00ff00ffffffffaa33eeffffaa77ffff00ffee00ff00ffff00ffcc44ff00ffee00ffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffbb0077110000ddffff66dd
+ffcc220066ffbb00ddaa00eeff2266ffffbb000077bb00ddaa00ee002222ccffff331188
+44ff2266ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffbb0077110000ddffff66ddffcc2200
+66ffbb00ddaa00ee2266ffffffffaa66443377ffffff33118844ff2266ff002222ccff33
+118844ffff2266ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff1100eeffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffff1100eeffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffccffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffccffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+%%EndData
+%%PageTrailer
+%%Trailer
+%%BoundingBox: 105 212 506 579
+%%EOF
diff --git a/lib/cosNotification/doc/src/part.xml b/lib/cosNotification/doc/src/part.xml
new file mode 100644
index 0000000000..06ae875c01
--- /dev/null
+++ b/lib/cosNotification/doc/src/part.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotification User's Guide</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev>1.0</rev>
+ </header>
+ <description>
+ <p>The <em>cosNotification</em> application is an Erlang implementation
+ of the OMG CORBA Notification Service.</p>
+ </description>
+ <xi:include href="ch_contents.xml"/>
+ <xi:include href="ch_introduction.xml"/>
+ <xi:include href="ch_install.xml"/>
+ <xi:include href="ch_system.xml"/>
+ <xi:include href="ch_BNF.xml"/>
+ <xi:include href="ch_QoS.xml"/>
+ <xi:include href="ch_example.xml"/>
+</part>
+
diff --git a/lib/cosNotification/doc/src/part_notes.xml b/lib/cosNotification/doc/src/part_notes.xml
new file mode 100644
index 0000000000..af262c3d0e
--- /dev/null
+++ b/lib/cosNotification/doc/src/part_notes.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotification Release Notes</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev>1.0</rev>
+ </header>
+ <description>
+ <p>The cosNotification Application is an Erlang implementation of the OMG
+ CORBA Notification Service.</p>
+ </description>
+ <xi:include href="notes.xml"/>
+</part>
+
diff --git a/lib/cosNotification/doc/src/ref_man.gif b/lib/cosNotification/doc/src/ref_man.gif
new file mode 100644
index 0000000000..b13c4efd53
--- /dev/null
+++ b/lib/cosNotification/doc/src/ref_man.gif
Binary files differ
diff --git a/lib/cosNotification/doc/src/ref_man.xml b/lib/cosNotification/doc/src/ref_man.xml
new file mode 100644
index 0000000000..1cf77c3c7f
--- /dev/null
+++ b/lib/cosNotification/doc/src/ref_man.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cosNotification Reference Manual</title>
+ <prepared>Niclas Eklund</prepared>
+ <docno></docno>
+ <date>2000-01-31</date>
+ <rev>1.0</rev>
+ </header>
+ <description>
+ <p>The <em>cosNotification</em> application is an Erlang implementation
+ of the OMG CORBA Notification Service.</p>
+ </description>
+ <xi:include href="cosNotificationApp.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_EventChannelFactory.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_EventChannel.xml"/>
+ <xi:include href="CosNotification.xml"/>
+ <xi:include href="CosNotification_QoSAdmin.xml"/>
+ <xi:include href="CosNotification_AdminPropertiesAdmin.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ConsumerAdmin.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_SupplierAdmin.xml"/>
+ <xi:include href="CosNotifyComm_NotifyPublish.xml"/>
+ <xi:include href="CosNotifyComm_NotifySubscribe.xml"/>
+ <xi:include href="CosNotifyFilter_FilterAdmin.xml"/>
+ <xi:include href="CosNotifyFilter_FilterFactory.xml"/>
+ <xi:include href="CosNotifyFilter_Filter.xml"/>
+ <xi:include href="CosNotifyFilter_MappingFilter.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ProxyConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ProxySupplier.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ProxyPullConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ProxyPullSupplier.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ProxyPushConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_ProxyPushSupplier.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml"/>
+ <xi:include href="CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml"/>
+</application>
+
diff --git a/lib/cosNotification/doc/src/summary.html.src b/lib/cosNotification/doc/src/summary.html.src
new file mode 100644
index 0000000000..92ade4f9cd
--- /dev/null
+++ b/lib/cosNotification/doc/src/summary.html.src
@@ -0,0 +1 @@
+Orber OMG Notification Service \ No newline at end of file
diff --git a/lib/cosNotification/doc/src/user_guide.gif b/lib/cosNotification/doc/src/user_guide.gif
new file mode 100644
index 0000000000..e6275a803d
--- /dev/null
+++ b/lib/cosNotification/doc/src/user_guide.gif
Binary files differ
diff --git a/lib/cosNotification/ebin/.gitignore b/lib/cosNotification/ebin/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/ebin/.gitignore
diff --git a/lib/cosNotification/examples/.gitignore b/lib/cosNotification/examples/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/examples/.gitignore
diff --git a/lib/cosNotification/include/.gitignore b/lib/cosNotification/include/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/include/.gitignore
diff --git a/lib/cosNotification/info b/lib/cosNotification/info
new file mode 100644
index 0000000000..1b634eb124
--- /dev/null
+++ b/lib/cosNotification/info
@@ -0,0 +1,3 @@
+group: orb
+short: Orber OMG Notification Service
+
diff --git a/lib/cosNotification/priv/.gitignore b/lib/cosNotification/priv/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/priv/.gitignore
diff --git a/lib/cosNotification/src/CosEvent.cfg b/lib/cosNotification/src/CosEvent.cfg
new file mode 100644
index 0000000000..e3399139a4
--- /dev/null
+++ b/lib/cosNotification/src/CosEvent.cfg
@@ -0,0 +1,20 @@
+{this, "CosEventChannelAdmin::EventChannel"}.
+{{handle_info, "CosEventChannelAdmin::EventChannel"}, true}.
+{this, "CosEventChannelAdmin::EventChannelFactory"}.
+{{handle_info, "CosEventChannelAdmin::EventChannelFactory"}, true}.
+{this, "CosEventChannelAdmin::SupplierAdmin"}.
+{{handle_info, "CosEventChannelAdmin::SupplierAdmin"}, true}.
+{this, "CosEventChannelAdmin::ConsumerAdmin"}.
+{{handle_info, "CosEventChannelAdmin::ConsumerAdmin"}, true}.
+{this, "CosEventChannelAdmin::ProxyPushSupplier"}.
+{{handle_info, "CosEventChannelAdmin::ProxyPushSupplier"}, true}.
+{{impl, "CosEventChannelAdmin::ProxyPushSupplier"}, "PusherSupplier_impl"}.
+{this, "CosEventChannelAdmin::ProxyPullSupplier"}.
+{{handle_info, "CosEventChannelAdmin::ProxyPullSupplier"}, true}.
+{{impl, "CosEventChannelAdmin::ProxyPullSupplier"}, "PullerSupplier_impl"}.
+{this, "CosEventChannelAdmin::ProxyPushConsumer"}.
+{{handle_info, "CosEventChannelAdmin::ProxyPushConsumer"}, true}.
+{{impl, "CosEventChannelAdmin::ProxyPushConsumer"}, "PusherConsumer_impl"}.
+{this, "CosEventChannelAdmin::ProxyPullConsumer"}.
+{{handle_info, "CosEventChannelAdmin::ProxyPullConsumer"}, true}.
+{{impl, "CosEventChannelAdmin::ProxyPullConsumer"}, "PullerConsumer_impl"}.
diff --git a/lib/cosNotification/src/CosNotification.cfg b/lib/cosNotification/src/CosNotification.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/src/CosNotification.cfg
diff --git a/lib/cosNotification/src/CosNotification.idl b/lib/cosNotification/src/CosNotification.idl
new file mode 100644
index 0000000000..e080b44b0c
--- /dev/null
+++ b/lib/cosNotification/src/CosNotification.idl
@@ -0,0 +1,146 @@
+#ifndef _COS_NOTIFICATION_IDL_
+#define _COS_NOTIFICATION_IDL_
+
+#pragma prefix "omg.org"
+
+#include"CosEventChannelAdmin.idl"
+#include"CosEventComm.idl"
+
+module CosNotification {
+ typedef string Istring;
+ typedef Istring PropertyName;
+ typedef any PropertyValue;
+ struct Property {
+ PropertyName name;
+ PropertyValue value;
+ };
+ typedef sequence<Property> PropertySeq;
+ // The following are the same, but serve different purposes.
+ typedef PropertySeq OptionalHeaderFields;
+ typedef PropertySeq FilterableEventBody;
+ typedef PropertySeq QoSProperties;
+ typedef PropertySeq AdminProperties;
+ struct EventType {
+ string domain_name;
+ string type_name;
+ };
+ typedef sequence<EventType> EventTypeSeq;
+ struct PropertyRange {
+ PropertyValue low_val;
+ PropertyValue high_val;
+ };
+ struct NamedPropertyRange {
+ PropertyName name;
+ PropertyRange range;
+ };
+
+ typedef sequence<NamedPropertyRange> NamedPropertyRangeSeq;
+
+ enum QoSError_code {
+ UNSUPPORTED_PROPERTY,
+ UNAVAILABLE_PROPERTY,
+ UNSUPPORTED_VALUE,
+ UNAVAILABLE_VALUE,
+ BAD_PROPERTY,
+ BAD_TYPE,
+ BAD_VALUE
+ };
+
+ struct PropertyError {
+ QoSError_code code;
+ PropertyName name;
+ PropertyRange available_range;
+ };
+
+ typedef sequence<PropertyError> PropertyErrorSeq;
+ exception UnsupportedQoS { PropertyErrorSeq qos_err; };
+ exception UnsupportedAdmin { PropertyErrorSeq admin_err; };
+
+ // Define the Structured Event structure
+ struct FixedEventHeader {
+ EventType event_type;
+ string event_name;
+ };
+ struct EventHeader {
+ FixedEventHeader fixed_header;
+ OptionalHeaderFields variable_header;
+ };
+
+ struct StructuredEvent {
+ EventHeader header;
+ FilterableEventBody filterable_data;
+ any remainder_of_body;
+ }; // StructuredEvent
+
+ typedef sequence<StructuredEvent> EventBatch;
+
+ // The following constant declarations define the standard
+ // QoS property names and the associated values each property
+ // can take on. The name/value pairs for each standard property
+ // are grouped, beginning with a string constant defined for the
+ // property name, followed by the values the property can take on.
+ const string EventReliability = "EventReliability";
+ const short BestEffort = 0;
+ const short Persistent = 1;
+ const string ConnectionReliability = "ConnectionReliability";
+
+ // Can take on the same values as EventReliability
+ const string Priority = "Priority";
+ const short LowestPriority = -32767;
+ const short HighestPriority = 32767;
+ const short DefaultPriority = 0;
+ const string StartTime = "StartTime";
+
+ // StartTime takes a value of type TimeBase::UtcT.
+ const string StopTime = "StopTime";
+ // StopTime takes a value of type TimeBase::UtcT.
+ const string Timeout = "Timeout";
+ // Timeout takes on a value of type TimeBase::TimeT
+ const string OrderPolicy = "OrderPolicy";
+ const short AnyOrder = 0;
+ const short FifoOrder = 1;
+ const short PriorityOrder = 2;
+ const short DeadlineOrder = 3;
+ const string DiscardPolicy = "DiscardPolicy";
+ // DiscardPolicy takes on the same values as OrderPolicy, plus
+ const short LifoOrder = 4;
+ const short RejectNewEvents = 5;
+ const string MaximumBatchSize = "MaximumBatchSize";
+ // MaximumBatchSize takes on a value of type long
+ const string PacingInterval = "PacingInterval";
+ // PacingInterval takes on a value of type TimeBase::TimeT
+ const string StartTimeSupported = "StartTimeSupported";
+ // StartTimeSupported takes on a boolean value
+ const string StopTimeSupported = "StopTimeSupported";
+ // StopTimeSupported takes on a boolean value
+ const string MaxEventsPerConsumer = "MaxEventsPerConsumer";
+ // MaxEventsPerConsumer takes on a value of type long
+
+ interface QoSAdmin {
+ QoSProperties get_qos();
+ void set_qos ( in QoSProperties qos)
+ raises ( UnsupportedQoS );
+ void validate_qos (in QoSProperties required_qos,
+ out NamedPropertyRangeSeq available_qos )
+ raises ( UnsupportedQoS );
+ }; // QosAdmin
+
+ // Admin properties are defined in similar manner as QoS
+ // properties. The only difference is that these properties
+ // are related to channel administration policies, as opposed
+ // message quality of service
+ const string MaxQueueLength = "MaxQueueLength";
+ // MaxQueueLength takes on a value of type long
+ const string MaxConsumers = "MaxConsumers";
+ // MaxConsumers takes on a value of type long
+ const string MaxSuppliers = "MaxSuppliers";
+ // MaxSuppliers takes on a value of type long
+ interface AdminPropertiesAdmin {
+ AdminProperties get_admin();
+ void set_admin (in AdminProperties admin)
+ raises ( UnsupportedAdmin);
+ };// AdminPropertiesAdmin
+}; // CosNotification
+
+#endif /* ifndef _COS_NOTIFICATION_IDL_ */
+
diff --git a/lib/cosNotification/src/CosNotification_Common.erl b/lib/cosNotification/src/CosNotification_Common.erl
new file mode 100644
index 0000000000..0e0f1da0d5
--- /dev/null
+++ b/lib/cosNotification/src/CosNotification_Common.erl
@@ -0,0 +1,1210 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%--------------------------------------------------------------------
+%% File : CosNotification_Common.erl
+%% Purpose :
+%%--------------------------------------------------------------------
+
+-module('CosNotification_Common').
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%% External MISC
+-export([get_option/3,
+ create_name/2,
+ create_name/1,
+ create_id/0,
+ create_id/1,
+ is_debug_compiled/0,
+ type_check/2,
+ send_stubborn/5,
+ create_link/3,
+ disconnect/3,
+ do_disconnect/3,
+ notify/1]).
+
+%% Internal AdminProperties
+-export([init_adm/1,
+ set_adm/2,
+ 'MaxQueueLength'/6,
+ 'MaxConsumers'/6,
+ 'MaxSuppliers'/6]).
+%% Internal QoS
+-export([init_qos/1,
+ set_qos/5,
+ validate_qos/5,
+ validate_event_qos/2,
+ 'EventReliability'/6,
+ 'ConnectionReliability'/6,
+ 'Priority'/6,
+ 'StartTimeSupported'/6,
+ 'StopTimeSupported'/6,
+ 'Timeout'/6,
+ 'OrderPolicy'/6,
+ 'DiscardPolicy'/6,
+ 'MaximumBatchSize'/6,
+ 'PacingInterval'/6,
+ 'MaxEventsPerConsumer'/6]).
+
+%%--------------- DEFINITIONS OF CONSTANTS -------------------
+%%--------------- EXTERNAL MISC FUNCTIONS --------------------
+%%------------------------------------------------------------
+%% function : create_link
+%% Arguments: Module - which Module to call
+%% Env/ArgList - ordinary oe_create arguments.
+%% Returns :
+%% Exception:
+%% Effect : Necessary since we want the supervisor to be a
+%% 'simple_one_for_one'. Otherwise, using for example,
+%% 'one_for_one', we have to call supervisor:delete_child
+%% to remove the childs startspecification from the
+%% supervisors internal state.
+%%------------------------------------------------------------
+create_link(Module, Env, ArgList) ->
+ Module:oe_create_link(Env, ArgList).
+
+%%-----------------------------------------------------------%
+%% function : get_option
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+get_option(Key, OptionList, DefaultList) ->
+ case lists:keysearch(Key, 1, OptionList) of
+ {value,{Key,Value}} ->
+ Value;
+ _ ->
+ case lists:keysearch(Key, 1, DefaultList) of
+ {value,{Key,Value}} ->
+ Value;
+ _->
+ {error, "Invalid option"}
+ end
+ end.
+%%-----------------------------------------------------------%
+%% function : create_name/2
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+create_name(Name,Type) ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat(['oe_',node(),'_',Type,'_',Name,'_',MSec, '_', Sec, '_', USec]).
+
+%%-----------------------------------------------------------%
+%% function : create_name/1
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+create_name(Type) ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]).
+
+%%------------------------------------------------------------
+%% function : create_id/0
+%% Arguments: -
+%% Returns : id (long) =/= 0
+%% Both default Admin:s have the unique id 0 (OMG spec, 98-11-01,
+%% Notification p 148), hence, we may not return 0.
+%% Exception:
+%% Purpose : Throughout the CosNotification service we use,
+%% according to the OMG specification, id:s (long),
+%% which must be "unique", to retrieve object references.
+%% For example: CosNotifyChannelAdmin::ChannelId/AdminID.
+%%------------------------------------------------------------
+create_id(-1) ->
+ 1;
+create_id( 2147483647) ->
+ -2147483648;
+create_id(OldID) ->
+ OldID+1.
+
+create_id() ->
+ {_A,_B,C}=now(),
+ C.
+
+%%-----------------------------------------------------------%
+%% function : type_check
+%% Arguments: Obj - objectrefernce to test.
+%% Mod - Module which contains typeID/0.
+%% Returns : 'ok' or raises exception.
+%% Effect :
+%%------------------------------------------------------------
+type_check(Obj, Mod) ->
+ case cosNotificationApp:type_check() of
+ false ->
+ ok;
+ _ ->
+ case catch corba_object:is_a(Obj,Mod:typeID()) of
+ true ->
+ ok;
+ false ->
+ orber:dbg("[~p] CosNotification_Common:type_check(~p);~n"
+ "The supplied Object is not or does not inherrit from: ~p",
+ [?LINE, Obj, Mod], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO});
+ {'EXCEPTION', E} ->
+ orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n"
+ "Failed due to: ~p",
+ [?LINE, Obj, Mod, E], ?DEBUG_LEVEL),
+ corba:raise(E);
+ What ->
+ orber:dbg("[~p] CosNotification_Common:type_check(~p, ~p);~n"
+ "Failed due to: ~p",
+ [?LINE, Obj, Mod, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end
+ end.
+
+
+%%-----------------------------------------------------------%
+%% function : notify
+%% Arguments: Items - [Item]
+%% Item - {proxy, IOR} | {client, IOR} | {reason, term()}
+%% Returns : 'ok' or raises exception.
+%% Effect :
+%%------------------------------------------------------------
+notify(Items) ->
+ case cosNotificationApp:notify() of
+ false ->
+ ok;
+ Module ->
+ catch Module:terminated(Items),
+ ok
+ end.
+
+
+%%------------------------------------------------------------
+%% function : send_stubborn
+%% Arguments: M - module
+%% F - function
+%% A - arguments
+%% MaxR - Maximum no retries
+%% Wait - sleep Wait seconds before next try.
+%% Returns : see effect
+%% Exception:
+%% Effect : Retries repeatidly untill anything else besides
+%% 'EXIT', 'COMM_FAILURE' or 'OBJECT_NOT_EXIST'
+%%------------------------------------------------------------
+
+send_stubborn(M, F, A, MaxR, Wait) when is_list(A) ->
+ send_stubborn(M, F, A, MaxR, Wait, 0);
+send_stubborn(M, F, A, MaxR, Wait) ->
+ send_stubborn(M, F, [A], MaxR, Wait, 0).
+send_stubborn(M, F, A, MaxR, _Wait, MaxR) ->
+ orber:dbg("[~p] CosNotification_Common:send_stubborn( ~p ~p ~p ~p).~n"
+ "Failed to deliver the event.~n", [?LINE, M,F,A,MaxR], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO});
+send_stubborn(M, F, A, MaxR, Wait, Times) ->
+ ?debug_print("~p:~p(~p) # of retries: ~p~n", [M,F,A, Times]),
+ case catch apply(M,F,A) of
+ {'EXCEPTION', E} when is_record(E, 'COMM_FAILURE')->
+ NewTimes = Times +1,
+ timer:sleep(Wait),
+ send_stubborn(M, F, A, MaxR, Wait, NewTimes);
+ {'EXIT', _} ->
+ NewTimes = Times +1,
+ timer:sleep(Wait),
+ send_stubborn(M, F, A, MaxR, Wait, NewTimes);
+ Other ->
+ Other
+ end.
+
+
+%%-----------------------------------------------------------%
+%% function : disconnect
+%% Arguments: Module - one of the interfaces defined in CosEventComm.
+%% Function - the appropriate disconnect function.
+%% Object - the client object reference.
+%% Returns : ok
+%% Exception:
+%% Effect : If the process would try to diconnect itself it could
+%% result in a deadlock. Hence, we spawn a new process to do it.
+%%------------------------------------------------------------
+disconnect(Module, Function, Object) ->
+ spawn(?MODULE, do_disconnect, [Module, Function, Object]),
+ ok.
+
+do_disconnect(Module, Function, Object) ->
+ catch Module:Function(Object),
+ ?DBG("Disconnect ~p:~p(..).~n", [Module, Function]),
+ ok.
+
+
+
+%%------------------------------------------------------------
+%% function : is_debug_compiled
+%% Arguments:
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+
+-ifdef(debug).
+ is_debug_compiled() -> true.
+-else.
+ is_debug_compiled() -> false.
+-endif.
+
+
+%%------------------------------------------------------------
+%%--------------- AdminPropertiesAdmin -----------------------
+%%------------------------------------------------------------
+%%------------------------------------------------------------
+%% function : init_adm
+%% Arguments: Wanted - requested Admins to be set.
+%% Returns : #'CosNotification_UnsupportedAdmin'{} |
+%% {NewAdmProperties, [MaxQ, MaxC, MaxS]}
+%% Effect : may only be used when creating a channel!!!!!!!!
+%%------------------------------------------------------------
+init_adm(Wanted) ->
+ {NewA,_} = set_properties(Wanted, ?not_DEFAULT_ADMINPROPERTIES, channelAdm,
+ ?not_SUPPORTED_ADMINPROPERTIES, [], [],
+ false, false, false),
+ {NewA, [extract_value(NewA, ?not_MaxQueueLength),
+ extract_value(NewA, ?not_MaxConsumers),
+ extract_value(NewA, ?not_MaxSuppliers)]}.
+
+set_adm(Wanted, Current) ->
+ {NewA,_} = set_properties(Wanted, Current, channelAdm,
+ ?not_SUPPORTED_ADMINPROPERTIES,
+ [], [], false, false, false),
+ {NewA, [extract_value(NewA, ?not_MaxQueueLength),
+ extract_value(NewA, ?not_MaxConsumers),
+ extract_value(NewA, ?not_MaxSuppliers)]}.
+
+'MaxQueueLength'(Req,channelAdm,_, _, _, _) -> admin_ok(Req).
+'MaxConsumers'(Req,channelAdm,_, _, _, _)-> admin_ok(Req).
+'MaxSuppliers'(Req,channelAdm,_, _, _, _)-> admin_ok(Req).
+
+admin_ok(Req) ->
+ case any:get_value(Req#'CosNotification_Property'.value) of
+ Val when is_integer(Val) andalso Val >= 0 ->
+ {ok, Req};
+ _ ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+
+%%------------------------------------------------------------
+%%--------------- QOS FUNCTIONS ------------------------------
+%%------------------------------------------------------------
+%%------------------------------------------------------------
+%% function : init_qos
+%% Arguments: Wanted - requested QoS to be set.
+%% Returns : see set_properties/9
+%% Effect : may only be used when creating a channel!!!!!!!!
+%%------------------------------------------------------------
+init_qos(Wanted) ->
+ LQS = set_local_qos(?not_DEFAULT_QOS, ?not_CreateInitQoS()),
+ set_properties(Wanted, ?not_DEFAULT_QOS, channel, ?not_SUPPORTED_QOS,
+ [], [], false, [], LQS).
+
+%%------------------------------------------------------------
+%% function : set_qos/5
+%% Arguments: Wanted - requested QoS to be set.
+%% Current - current QoS OMG style
+%% LQS - local representation of QoS.
+%% Type - channel | admin | proxy
+%% Parent - Factory if Channel, Channel if Admin etc
+%% Childs - Admins if Channel etc
+%% Returns : see set_properties/9
+%%------------------------------------------------------------
+set_qos(Wanted, {Current, LQS}, proxy, Parent, _) ->
+ set_properties(Wanted, Current, proxy, ?not_SUPPORTED_QOS, [], [], Parent, false,LQS);
+set_qos(Wanted, {Current, LQS}, admin, Parent, Childs) ->
+ set_properties(Wanted, Current, admin, ?not_SUPPORTED_QOS, [], [], Parent, Childs,LQS);
+set_qos(Wanted, {Current, LQS}, channel, _, Childs) ->
+ set_properties(Wanted, Current, channel, ?not_SUPPORTED_QOS, [], [], false, Childs,LQS).
+
+%%------------------------------------------------------------
+%% function :
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns : ok - if requested equal to current value.
+%% {ok, Req, LQS} - if new and allowed QoS
+%% {unsupported,#'CosNotification_PropertyError'{}} otherwise.
+%% Effect :
+%%------------------------------------------------------------
+'EventReliability'(Req,channel, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, _, Val, _} ->
+ {ok, Req, LQS};
+ {Val, _, _, Val} ->
+ {ok, Req, LQS};
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end;
+'EventReliability'(Req,_,_,_,_,_) ->
+ %% only valid to set this QoS for channels (or per-event).
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNAVAILABLE_PROPERTY',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }.
+
+%%------------------------------------------------------------
+%% function : 'ConnectionReliability'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Exception:
+%% Effect :
+%%------------------------------------------------------------
+%% The most complex QoS to set is ConnectionReliability, and the reason for this
+%% is that we cannot set the Channel to offer best effort while its children
+%% offer persistent. A child may only offer Persistent if its parent do, which
+%% is why we must check the following:
+%%
+%% # Persistent Change to Best Effort
+%% _____
+%% | | (1) -> Check if children BE
+%% |Chann| (2) ok <-
+%% -----
+%% |
+%% _____
+%% | | (3) -> Check if children BE
+%% |Admin| (4) Check if parent Pers. <-
+%% -----
+%% |
+%% _____
+%% | | (5) -> ok
+%% |Proxy| (6) Check if parent Pers. <-
+%% -----
+%% NOTE: a parent always exists but we may change the QoS before creating any
+%% childrens. The cases (2) and (5) is always ok, i.e., no need to confirm
+%% with parent or children.
+%%------------------------------------------------------------
+'ConnectionReliability'(Req, channel, _Curr, _Parent, Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, P, Val, P} ->
+ %% Requested is BestEffort, Current Persistent => (1)
+ check_with_relatives(Childs, Req, LQS);
+ {Val, B, B, Val} ->
+ %% Requested is Persistent, Current BestEffort => (2)
+ {ok, Req, LQS};
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end;
+'ConnectionReliability'(Req, admin, _Curr, Parent, Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, P, Val, P} ->
+ %% Requested is BestEffort, Current Persistent => (3)
+ check_with_relatives(Childs, Req, LQS);
+ {Val, B, B, Val} ->
+ %% Requested is Persistent, Current BestEffort => (4)
+ check_with_relatives([Parent], Req, LQS);
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end;
+'ConnectionReliability'(Req, proxy, _Curr, Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetConnectionReliability(LQS), ?not_BestEffort, ?not_Persistent} of
+ {Val, Val, _, _} ->
+ %% Is the value requested.
+ ok;
+ {Val, P, Val, P} ->
+ %% Requested is BestEffort, Current Persistent => (5)
+ {ok, Req, LQS};
+ {Val, B, B, Val} ->
+ %% Requested is Persistent, Current BestEffort => (6)
+ check_with_relatives([Parent], Req, LQS);
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'Priority'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'Priority'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetPriority(LQS), ?not_HighestPriority, ?not_LowestPriority} of
+ {Val, Val, _, _} ->
+ ok;
+ {Val, _, H, L} when Val =< H, Val >= L ->
+ {ok, Req, LQS};
+ {_, _, H, L} ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), L),
+ high_val=any:create(orber_tc:short(), H)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'StartTimeSupported'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'StartTimeSupported'(Req, _Type, _Curr, _, _, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetStartTimeSupported(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val =/= true, Val =/= false ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:boolean(), false),
+ high_val=any:create(orber_tc:boolean(), true)
+ }
+ }
+ };
+ _->
+ {ok, Req, LQS}
+ end.
+
+%%------------------------------------------------------------
+%% function : 'StopTimeSupported'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'StopTimeSupported'(Req, _Type, _Curr, _, _, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetStopTimeSupported(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val =/= true, Val =/= false ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:boolean(), false),
+ high_val=any:create(orber_tc:boolean(), true)
+ }
+ }
+ };
+ _->
+ {ok, Req, LQS}
+ end.
+
+%%------------------------------------------------------------
+%% function : 'Timeout'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'Timeout'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetTimeout(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val >= ?not_MinTimeout, Val =< ?not_MaxTimeout ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinTimeout),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxTimeout)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'OrderPolicy'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'OrderPolicy'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetOrderPolicy(LQS), 'CosNotification':'AnyOrder'(),
+ 'CosNotification':'PriorityOrder'()} of
+ {Val, Val,_,_} ->
+ ok;
+ {Val, _, L, H} when Val >= L, Val =< H ->
+ {ok, Req, LQS};
+ {Val, _, L, H} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), L),
+ high_val=any:create(orber_tc:short(), H)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+
+%%------------------------------------------------------------
+%% function : 'DiscardPolicy'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'DiscardPolicy'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetDiscardPolicy(LQS), ?not_AnyOrder, ?not_PriorityOrder} of
+ {Val, Val,_,_} ->
+ ok;
+ {Val, _, L, H} when Val >= L, Val =< H ->
+ {ok, Req, LQS};
+ {Val, _, L, H} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), L),
+ high_val=any:create(orber_tc:short(), H)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'DiscardPolicy'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'MaximumBatchSize'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetMaximumBatchSize(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val >= ?not_MinBatchSize, Val =< ?not_MaxBatchSize ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinBatchSize),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxBatchSize)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNSUPPORTED_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:long(), ?not_MinBatchSize),
+ high_val=any:create(orber_tc:long(), ?not_MaxBatchSize)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'PacingInterval'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Comment : PacingInterval is defined to be:
+%% * TimeBase::UtcT (p 57, 2.5.5, OMG TC Document telecom/98-11-01)
+%% * TimeBase::TimeT (p 189, appendix B, OMG TC Document telecom/98-11-01)
+%% This implementation use TimeBase::TimeT, especially since
+%% TimeBase::UtcT contains information which are of no importance.
+%% When writing this, the OMG homepage contained no information
+%% regarding this.
+%%------------------------------------------------------------
+'PacingInterval'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetPacingInterval(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when Val >= ?not_MinPacing, Val =< ?not_MaxPacing ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinPacing),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxPacing)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_TYPE',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : 'MaxEventsPerConsumer'/6
+%% Arguments: Req - Requested QoS, #'CosNotification_Property'{}
+%% Type - Requestee, channel | admin | proxy
+%% Curr - Current QoS, #'CosNotification_Property'{}
+%% Parent - false | ObjRef
+%% Childs - false | [ObjRef1, .., ObjRefN]
+%% LQS - #qos{} defined in CosNotification_Definitions.hrl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+'MaxEventsPerConsumer'(Req, _Type, _Curr, _Parent, _Childs, LQS) ->
+ case {any:get_value(Req#'CosNotification_Property'.value),
+ ?not_GetMaxEventsPerConsumer(LQS)} of
+ {Val, Val} ->
+ ok;
+ {Val, _} when is_integer(Val) andalso
+ Val >= ?not_MinConsumerEvents andalso
+ Val =< ?not_MaxConsumerEvents ->
+ {ok, Req, LQS};
+ {Val, _} when is_integer(Val) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinConsumerEvents),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxConsumerEvents)
+ }
+ }
+ };
+ _->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNSUPPORTED_VALUE',
+ name = Req#'CosNotification_Property'.name,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents),
+ high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents)
+ }
+ }
+ }
+ end.
+
+%%------------------------------------------------------------
+%% function : validate_qos/5
+%% Arguments: Wanted - requested QoS to be set.
+%% Curr - current QoS OMG style and LQS, local
+%% representation of QoS, grouped as {OMGQ, LQS}
+%% Type - channel | admin | proxy
+%% Parent - Factory if Channel, Channel if Admin etc
+%% Childs - Admins if Channel etc
+%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{}
+%% case 1 if all supported, case 2 if at least 1 QoS not
+%% supported.
+%% See also p59, 2.5.6.4, OMG TC Document telecom/98-11-01. Quote:
+%% "If the supplied QoS is supported, it returns additional QoS
+%% properties which could be optionally added as well."
+%%------------------------------------------------------------
+validate_qos(Wanted, Curr, Type, Parent, Childs) ->
+ %% If not supported this function will raise an exception, which we should
+ %% not catch, but all we need to is to raise the exception as it is.
+ {_, LQS}=set_qos(Wanted, Curr, Type, Parent, Childs),
+ NewNPR = check_limits(LQS, ?not_QOS_LIMITS),
+ remove_qos(Wanted, LQS, NewNPR).
+
+remove_qos([], _, NPR) ->
+ NPR;
+remove_qos([H|T], LQS, NPR) ->
+ NewNPR=remove(NPR, H#'CosNotification_Property'.name),
+ remove_qos(T, LQS, NewNPR).
+
+check_limits(LQS, NPR) ->
+ case {?not_GetEventReliability(LQS), ?not_GetConnectionReliability(LQS),
+ ?not_Persistent, ?not_BestEffort} of
+ {P,P,P,_B} ->
+ New = #'CosNotification_NamedPropertyRange'
+ {name=?not_EventReliability,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_BestEffort),
+ high_val=any:create(orber_tc:short(), ?not_BestEffort)
+ }},
+ NewNPR=change(NPR, ?not_EventReliability, New),
+ remove(NewNPR, ?not_ConnectionReliability);
+ {_,B,_P,B} ->
+ remove(NPR, ?not_EventReliability);
+ {B,P,P,B} ->
+ New = #'CosNotification_NamedPropertyRange'
+ {name=?not_ConnectionReliability,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_BestEffort),
+ high_val=any:create(orber_tc:short(), ?not_BestEffort)
+ }},
+ change(NPR, ?not_ConnectionReliability, New)
+ end.
+
+%%------------------------------------------------------------
+%% function : validate_event_qos/2
+%% Arguments: Wanted - requested QoS to be set.
+%% Curr - LQS, local representation of QoS
+%% Returns : NamedPropertySeq | #'CosNotification_UnsupportedQoS'{}
+%% case 1 if all supported, case 2 if at least 1 QoS not
+%% supported.
+%%------------------------------------------------------------
+validate_event_qos(Wanted, Curr) ->
+ v_e_q_helper(Wanted, Curr, []),
+ [].
+v_e_q_helper([], _Curr, []) ->
+ %% Parsed all and foynd no conflicts.
+ ok;
+v_e_q_helper([], _Curr, Unsupp) ->
+ %% Not possible to use these requested QoS.
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});
+
+%%--- EventReliability ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability,
+ value=#any{value=?not_BestEffort}}|T], Curr, Unsupp) ->
+ %% Always ok.
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability,
+ value=#any{value=?not_Persistent}}|T], Curr, Unsupp)
+ when ?not_GetConnectionReliability(Curr) =/= ?not_BestEffort,
+ ?not_GetEventReliability(Curr) =/= ?not_BestEffort,
+ ?not_GetStopTimeSupported(Curr) =/= true ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability}|T],
+ Curr, Unsupp) ->
+ %% Impossible to set to Persistent if the connection reliability is best effort.
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_EventReliability,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)}}|Unsupp]);
+
+%%--- Priority ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_Priority, value=#any{value=V}}|T], Curr,
+ Unsupp) ->
+ if
+ ?not_GetOrderPolicy(Curr) =/= ?not_AnyOrder,
+ ?not_GetOrderPolicy(Curr) =/= ?not_Priority,
+ ?not_GetDiscardPolicy(Curr) =/= ?not_Priority ->
+ %% No use setting Priority since it's not currently used.
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_Priority,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+ V =< ?not_HighestPriority, V >= ?not_LowestPriority ->
+ v_e_q_helper(T, Curr, Unsupp);
+ true ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'BAD_VALUE', name = ?not_Priority,
+ available_range =
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(),
+ ?not_LowestPriority),
+ high_val=any:create(orber_tc:short(),
+ ?not_HighestPriority)}}|Unsupp])
+ end;
+
+%%--- StartTime ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp)
+ when ?not_GetStartTimeSupported(Curr) =/= false,
+ ?not_GetEventReliability(Curr) =/= ?not_Persistent ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_StartTime}|T], Curr, Unsupp) ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_StartTime,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+
+%%--- StopTime ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp)
+ when ?not_GetStopTimeSupported(Curr) =/= false,
+ ?not_GetEventReliability(Curr) =/= ?not_Persistent ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_StopTime}|T], Curr, Unsupp) ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_StopTime,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+
+%%--- Timeout ---%%
+v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp)
+ when ?not_GetStopTimeSupported(Curr) =/= false,
+ ?not_GetEventReliability(Curr) =/= ?not_Persistent ->
+ v_e_q_helper(T, Curr, Unsupp);
+v_e_q_helper([#'CosNotification_Property'{name=?not_Timeout}|T], Curr, Unsupp) ->
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'UNAVAILABLE_VALUE', name = ?not_Timeout,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+
+%%--- Unknown Event QoS ---%%
+v_e_q_helper([#'CosNotification_Property'{name=Name}|T], Curr, Unsupp) ->
+ %% Unsupported property.
+ v_e_q_helper(T, Curr, [#'CosNotification_PropertyError'
+ {code = 'BAD_PROPERTY', name = Name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }}|Unsupp]);
+v_e_q_helper(What, _, _) ->
+ %% Not a Property struct.
+ orber:dbg("[~p] CosNotification_Common:v_e_q_helper(~p);~n"
+ "Not a CosNotification_Property struct.",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%-------------- QOS HELP FUNCTIONS --------------------------
+%%------------------------------------------------------------
+%% function : set_properties/9
+%% Arguments: Wanted - requested QoS to be set.
+%% Current - current QoS OMG style
+%% Type - channel | admin | proxy
+%% Supported - List of supported QoS
+%% Unsupp - acc
+%% NewQoS - acc
+%% Parent - Factory if Channel, Channel if Admin etc
+%% Childs - Admins if Channel etc
+%% LQS - local representation of QoS.
+%% Returns : {NewOMGStyleQoS, NewLocalQoS} | #'CosNotification_UnsupportedQoS'{}
+%%------------------------------------------------------------
+set_properties([], Curr, channelAdm, _, [], NewQoS,_,_,LAS) ->
+ merge_properties(NewQoS, Curr, LAS);
+set_properties([], Curr, _, _, [], NewQoS,_,_,LQS) ->
+ %% set_local_qos and merge_properties are help functions found at the end of QoS
+ %% functions.
+ NewLQS = set_local_qos(NewQoS, LQS),
+ merge_properties(NewQoS, Curr, NewLQS);
+set_properties([], _, channelAdm, _, Unsupp, _,_,_,_) ->
+ corba:raise(#'CosNotification_UnsupportedAdmin'{admin_err = Unsupp});
+set_properties([], _, _, _, Unsupp, _,_,_,_) ->
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});
+
+set_properties([Req|Tail], Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) ->
+ %% set_values and is_supported are help functions found at the end of QoS
+ %% functions.
+ case set_values(is_supported(Supported, Req), Req, Type, Curr, Parent, Childs,LQS) of
+ {unsupported, U} ->
+ set_properties(Tail, Curr, Type, Supported, [U|Unsupp], NewQoS, Parent, Childs,LQS);
+ {ok, S, NewLQS} ->
+ set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,NewLQS);
+ {ok, S} ->
+ set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,LQS);
+ ok ->
+ set_properties(Tail, Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS)
+ end.
+
+
+set_values(unsupported,Req,_,_,_,_,_) ->
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'BAD_PROPERTY',
+ name = Req#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ };
+set_values({ok, Func}, Req, Type, Curr, Parent, Childs, LQS) ->
+ ?MODULE:Func(Req, Type, Curr, Parent, Childs, LQS).
+
+%% Update OMG style QoS list with new values.
+merge_properties([], NewCurrQoS, LQS) ->
+ {NewCurrQoS, LQS};
+merge_properties([H|T], Curr, LQS) ->
+ merge_properties(T, lists:keyreplace(H#'CosNotification_Property'.name, %% get key.
+ #'CosNotification_Property'.name, %% get index.
+ Curr, H), LQS).
+
+%% Is the Property S among our supported QoS?
+is_supported([], _) ->
+ unsupported;
+is_supported([{Name, Func}|_], #'CosNotification_Property'{name=Name}) ->
+ {ok, Func};
+is_supported([_|T], S) ->
+ is_supported(T, S).
+
+%% Find matching S-Property from a list of OMG style QoS
+extract([], _) -> unsupported;
+extract([H|_T], S) when H#'CosNotification_Property'.name==
+ S#'CosNotification_Property'.name ->
+ {ok, H};
+extract([_|T], S) -> extract(T,S).
+
+%% Find matching Property name from a list of OMG style QoS
+extract_value([], _) -> unsupported;
+extract_value([H|_T], Key) when H#'CosNotification_Property'.name== Key ->
+ {ok, any:get_value(H#'CosNotification_Property'.value)};
+extract_value([_|T], Key) -> extract(T,Key).
+
+%% Remove matching S-QoS from a list of OMG style QoS
+remove(List, Key) ->
+ lists:keydelete(Key,
+ #'CosNotification_NamedPropertyRange'.name, %% get index.
+ List).
+
+change(List, Key, New) ->
+ lists:keyreplace(Key,
+ #'CosNotification_NamedPropertyRange'.name, %% get index.
+ List, New).
+%% Get QoS from supplied objects and check if it's the same as S.
+check_with_relatives([], S, LQS) ->
+ {ok, S, LQS};
+check_with_relatives([undefined|T], S, LQS) ->
+ check_with_relatives(T, S, LQS);
+check_with_relatives([H|T], S, LQS) ->
+ case catch extract('CosNotification_QoSAdmin':get_qos(H), S) of
+ {ok, S} ->
+ check_with_relatives(T, S, LQS);
+ _->
+ %% Varioues reasons for this case (Object not responding, not supported)
+ {unsupported,
+ #'CosNotification_PropertyError'{
+ code = 'UNAVAILABLE_PROPERTY',
+ name = S#'CosNotification_Property'.name,
+ available_range = #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:null(), null),
+ high_val=any:create(orber_tc:null(), null)
+ }
+ }
+ }
+ end.
+
+%% Set new values to locally defined representation of QoS. Using this approach is
+%% necessary since we must state the record-field at compile-time.
+set_local_qos([], LQS) -> LQS;
+set_local_qos([#'CosNotification_Property'{name=N,value=V}|T], LQS) ->
+ NewLQS =
+ case N of
+ "EventReliability" ->
+ ?not_SetEventReliability(LQS, any:get_value(V));
+ "ConnectionReliability" ->
+ ?not_SetConnectionReliability(LQS, any:get_value(V));
+ "Priority" ->
+ ?not_SetPriority(LQS, any:get_value(V));
+ "Timeout" ->
+ ?not_SetTimeout(LQS, any:get_value(V));
+ "OrderPolicy" ->
+ ?not_SetOrderPolicy(LQS, any:get_value(V));
+ "DiscardPolicy" ->
+ ?not_SetDiscardPolicy(LQS, any:get_value(V));
+ "MaximumBatchSize" ->
+ ?not_SetMaximumBatchSize(LQS, any:get_value(V));
+ "PacingInterval" ->
+ ?not_SetPacingInterval(LQS, any:get_value(V));
+ "StartTimeSupported" ->
+ ?not_SetStartTimeSupported(LQS, any:get_value(V));
+ "StopTimeSupported" ->
+ ?not_SetStopTimeSupported(LQS, any:get_value(V));
+ "MaxEventsPerConsumer" ->
+ ?not_SetMaxEventsPerConsumer(LQS, any:get_value(V))
+ end,
+ set_local_qos(T, NewLQS).
+
+%%%%%%%%%%%%%%%%% END QOS FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotification_Definitions.hrl b/lib/cosNotification/src/CosNotification_Definitions.hrl
new file mode 100644
index 0000000000..755b07cd5d
--- /dev/null
+++ b/lib/cosNotification/src/CosNotification_Definitions.hrl
@@ -0,0 +1,340 @@
+%%----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : CosNotification_Definitions.hrl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-ifndef(COSNOTIFICATION_DEFINITIONS_HRL).
+-define(COSNOTIFICATION_DEFINITIONS_HRL, true).
+
+%% ---------------- General comment ------------------------------------
+%% ******* README ********
+%% The prefix 'not' is short for notification, and is used to separate locally
+%% defined macros from the global ones, i.e., do NOT confuse this with a negation!!
+%%
+%% In this file you find globally used data structures, constants etc.
+%%
+
+%%--------------- INCLUDES ---------------------------------------------
+
+%%-------- Constants -------------------------------------------------
+-define(not_SupportedGrammars, ["EXTENDED_TCL"]).
+
+%% !!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+%%
+%% If OMG redefines the values for the constants the definitions
+%% below must be redefined!!
+%%
+%% !!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+-define(not_BestEffort, 0).
+-define(not_Persistent, 1).
+-define(not_EventReliability, "EventReliability").
+-define(not_ConnectionReliability, "ConnectionReliability").
+-define(not_Priority, "Priority").
+-define(not_LowestPriority, -32767).
+-define(not_HighestPriority, 32767).
+-define(not_DefaultPriority, 0).
+-define(not_StartTime, "StartTime").
+-define(not_StopTime, "StopTime").
+-define(not_Timeout, "Timeout").
+-define(not_OrderPolicy, "OrderPolicy").
+-define(not_AnyOrder, 0).
+-define(not_FifoOrder, 1).
+-define(not_PriorityOrder, 2).
+-define(not_DeadlineOrder, 3).
+-define(not_DiscardPolicy, "DiscardPolicy").
+-define(not_LifoOrder, 4).
+-define(not_RejectNewEvents, 5).
+-define(not_MaximumBatchSize, "MaximumBatchSize").
+-define(not_PacingInterval, "PacingInterval").
+-define(not_StartTimeSupported, "StartTimeSupported").
+-define(not_StopTimeSupported, "StopTimeSupported").
+-define(not_MaxEventsPerConsumer, "MaxEventsPerConsumer").
+-define(not_MaxQueueLength, "MaxQueueLength").
+-define(not_MaxConsumers, "MaxConsumers").
+-define(not_MaxSuppliers, "MaxSuppliers").
+
+%%--------------- QOS DEFINITIONS ----------------------------
+%% Limits for QoS. These are our own limits.
+-define(not_MaxBatchSize, 10000).
+-define(not_MinBatchSize, 1).
+-define(not_MinTimeout, 0).
+-define(not_MaxTimeout, 100000000000).
+-define(not_MinPacing, 0).
+-define(not_MaxPacing, 100000000000).
+-define(not_MinConsumerEvents, 1).
+-define(not_MaxConsumerEvents, 10000).
+
+-define(not_QOS_LIMITS,
+[#'CosNotification_NamedPropertyRange'
+ {name=?not_EventReliability,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_BestEffort),
+ high_val=any:create(orber_tc:short(), ?not_Persistent)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_ConnectionReliability,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_BestEffort),
+ high_val=any:create(orber_tc:short(), ?not_Persistent)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_Priority,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_LowestPriority),
+ high_val=any:create(orber_tc:short(), ?not_HighestPriority)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_StartTimeSupported,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:boolean(), false),
+ high_val=any:create(orber_tc:boolean(), true)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_StopTimeSupported,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:boolean(), false),
+ high_val=any:create(orber_tc:boolean(), true)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_Timeout,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinTimeout),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxTimeout)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_OrderPolicy,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_AnyOrder),
+ high_val=any:create(orber_tc:short(), ?not_PriorityOrder)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_DiscardPolicy,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:short(), ?not_AnyOrder),
+ high_val=any:create(orber_tc:short(), ?not_PriorityOrder)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_MaximumBatchSize,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:long(), ?not_MinBatchSize),
+ high_val=any:create(orber_tc:long(), ?not_MaxBatchSize)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_PacingInterval,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:unsigned_long_long(), ?not_MinPacing),
+ high_val=any:create(orber_tc:unsigned_long_long(), ?not_MaxPacing)
+ }},
+ #'CosNotification_NamedPropertyRange'
+ {name=?not_MaxEventsPerConsumer,
+ range=
+ #'CosNotification_PropertyRange'{
+ low_val=any:create(orber_tc:long(), ?not_MinConsumerEvents),
+ high_val=any:create(orber_tc:long(), ?not_MaxConsumerEvents)
+ }}
+].
+
+
+
+%% Local record used internally, and the reason for this is we get faster
+%% access to QoS settings.
+-record(qos, {'EventReliability',
+ 'ConnectionReliability',
+ 'Priority',
+ 'StartTimeSupported',
+ 'StopTimeSupported',
+ 'Timeout',
+ 'OrderPolicy',
+ 'DiscardPolicy',
+ 'MaximumBatchSize',
+ 'PacingInterval',
+ 'MaxEventsPerConsumer'}).
+
+%% Global (OMG) representation of QoS.
+-define(not_DEFAULT_QOS,
+[#'CosNotification_Property'{name=?not_MaximumBatchSize,
+ value=any:create(orber_tc:long(), 1)},
+ #'CosNotification_Property'{name=?not_PacingInterval,
+ value=any:create(orber_tc:unsigned_long_long(), 0)},
+ #'CosNotification_Property'{name=?not_Timeout,
+ value=any:create(orber_tc:unsigned_long_long(), 0)},
+ #'CosNotification_Property'{name=?not_MaxEventsPerConsumer,
+ value=any:create(orber_tc:long(), 100)},
+ #'CosNotification_Property'{name=?not_OrderPolicy,
+ value=any:create(orber_tc:short(),
+ ?not_PriorityOrder)},
+ #'CosNotification_Property'{name=?not_EventReliability,
+ value=any:create(orber_tc:short(),
+ ?not_BestEffort)},
+ #'CosNotification_Property'{name=?not_ConnectionReliability,
+ value=any:create(orber_tc:short(),
+ ?not_BestEffort)},
+ #'CosNotification_Property'{name=?not_DiscardPolicy,
+ value=any:create(orber_tc:short(),
+ ?not_RejectNewEvents)},
+ #'CosNotification_Property'{name=?not_StartTimeSupported,
+ value=any:create(orber_tc:boolean(), false)},
+ #'CosNotification_Property'{name=?not_StopTimeSupported,
+ value=any:create(orber_tc:boolean(), false)},
+ #'CosNotification_Property'{name=?not_Priority,
+ value=any:create(orber_tc:short(), ?not_DefaultPriority)}]).
+
+%%--------------- QOS CREATORS -------------------------------
+-define(not_CreateInitQoS(), #qos{}).
+
+%%--------------- QOS DESTRUCTORS ----------------------------
+-define(not_DestroyQoS(Q), ok).
+
+%%--------------- QOS SELECTORS ------------------------------
+-define(not_GetEventReliability(Q), Q#qos.'EventReliability').
+-define(not_GetConnectionReliability(Q), Q#qos.'ConnectionReliability').
+-define(not_GetPriority(Q), Q#qos.'Priority').
+-define(not_GetStartTimeSupported(Q), Q#qos.'StartTimeSupported').
+-define(not_GetStopTimeSupported(Q), Q#qos.'StopTimeSupported').
+-define(not_GetTimeout(Q), Q#qos.'Timeout').
+-define(not_GetOrderPolicy(Q), Q#qos.'OrderPolicy').
+-define(not_GetDiscardPolicy(Q), Q#qos.'DiscardPolicy').
+-define(not_GetMaximumBatchSize(Q), Q#qos.'MaximumBatchSize').
+-define(not_GetPacingInterval(Q), Q#qos.'PacingInterval').
+-define(not_GetMaxEventsPerConsumer(Q), Q#qos.'MaxEventsPerConsumer').
+
+%%--------------- QOS MODIFIERS ------------------------------
+-define(not_SetEventReliability(Q,D), Q#qos{'EventReliability'=D}).
+-define(not_SetConnectionReliability(Q,D), Q#qos{'ConnectionReliability'=D}).
+-define(not_SetPriority(Q,D), Q#qos{'Priority'=D}).
+-define(not_SetStartTimeSupported(Q,D), Q#qos{'StartTimeSupported'=D}).
+-define(not_SetStopTimeSupported(Q,D), Q#qos{'StopTimeSupported'=D}).
+-define(not_SetTimeout(Q,D), Q#qos{'Timeout'=D}).
+-define(not_SetOrderPolicy(Q,D), Q#qos{'OrderPolicy'=D}).
+-define(not_SetDiscardPolicy(Q,D), Q#qos{'DiscardPolicy'=D}).
+-define(not_SetMaximumBatchSize(Q,D), Q#qos{'MaximumBatchSize'=D}).
+-define(not_SetPacingInterval(Q,D), Q#qos{'PacingInterval'=D}).
+-define(not_SetMaxEventsPerConsumer(Q,D), Q#qos{'MaxEventsPerConsumer'=D}).
+
+%%--------------- StructuredEvent CREATORS -------------------
+-define(not_CreateSE(StrD,StrT,StrE,PSeqV,PSeqF,AnyR),
+#'CosNotification_StructuredEvent'{header =
+ #'CosNotification_EventHeader'{fixed_header =
+ #'CosNotification_FixedEventHeader'{event_type =
+ #'CosNotification_EventType'{domain_name=StrD,
+ type_name=StrT},
+ event_name = StrE},
+ variable_header = PSeqV},
+ filterable_data = PSeqF,
+ remainder_of_body = AnyR}).
+%% Can be used in guards.
+-define(not_isConvertedAny(E),
+ (((E#'CosNotification_StructuredEvent'.header)
+ #'CosNotification_EventHeader'.fixed_header)
+ #'CosNotification_FixedEventHeader'.event_type)
+ #'CosNotification_EventType'.type_name == "%ANY").
+%% Can NOT be used in guards!!!!!
+-define(not_isConvertedStructured(E),
+ any:get_typecode(E) == 'CosNotification_StructuredEvent':tc()).
+
+%%--------------- StructuredEvent DESTRUCTORS ----------------
+-define(not_DestroySE(E), ok).
+
+%%--------------- StructuredEvent SELECTORS ------------------
+-define(not_GetSEHeader(E), E#'StructuredEvent'.header).
+-define(not_GetSEFixedHeader(E), E#'StructuredEvent'.header).
+
+%%--------------- StructuredEvent MODIFIERS ------------------
+
+%%-------- QoS support -----------------------------------------------
+-define(not_SUPPORTED_QOS,
+[{?not_EventReliability, 'EventReliability'},
+ {?not_ConnectionReliability, 'ConnectionReliability'},
+ {?not_Priority, 'Priority'},
+ {?not_StartTimeSupported, 'StartTimeSupported'},
+ {?not_StopTimeSupported, 'StopTimeSupported'},
+ {?not_Timeout, 'Timeout'},
+ {?not_OrderPolicy, 'OrderPolicy'},
+ {?not_DiscardPolicy, 'DiscardPolicy'},
+ {?not_MaximumBatchSize, 'MaximumBatchSize'},
+ {?not_PacingInterval, 'PacingInterval'},
+ {?not_MaxEventsPerConsumer, 'MaxEventsPerConsumer'}]).
+
+%%-------- ADMINPROPERTIESADMIN --------------------------------------
+
+%% According to the OMG TC Document telecom/98-11-01, p 63 (section 2.5.7), the
+%% default-value for these 3 admin properties is zero, which means that no limit
+%% applies to that property.
+-define(not_DEFAULT_ADMINPROPERTIES,
+[#'CosNotification_Property'{name=?not_MaxQueueLength,
+ value=any:create(orber_tc:long(), 0)},
+ #'CosNotification_Property'{name=?not_MaxConsumers,
+ value=any:create(orber_tc:long(), 0)},
+ #'CosNotification_Property'{name=?not_MaxSuppliers,
+ value=any:create(orber_tc:long(), 0)}]).
+
+-define(not_SUPPORTED_ADMINPROPERTIES,
+[{?not_MaxQueueLength, 'MaxQueueLength'},
+ {?not_MaxConsumers, 'MaxConsumers'},
+ {?not_MaxSuppliers, 'MaxSuppliers'}]).
+
+
+%%-------- MISC --------------------------------------------------------
+
+-define(not_DEFAULT_SETTINGS, [{pullInterval, 20},
+ {filterOp, 'OR_OP'},
+ {gcTime, 60},
+ {gcLimit, 50},
+ {timeService, undefined},
+ {typecheck, true},
+ {tty, false},
+ {logfile, false},
+ {server_options, []}]).
+-define(not_CreateDBKey, term_to_binary({now(), node()})).
+
+-define(DEBUG_LEVEL, 3).
+
+-ifdef(debug).
+
+-define(debug_print(F,A), io:format("[~p(~p)] "++F,[?MODULE, ?LINE]++A)).
+-define(DBG(F,A), io:format("[~p(~p)] "++F,[?MODULE, ?LINE]++A)).
+-define(not_TypeCheck(O,I), ok).
+%-define(not_TypeCheck(O,M), 'CosNotification_Common':type_check(O,M)).
+
+-else.
+
+-define(debug_print(F,A), ok).
+-define(DBG(F,A), ok).
+-define(not_TypeCheck(O,I), ok).
+
+-endif.
+
+
+
+-endif.
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin.cfg b/lib/cosNotification/src/CosNotifyChannelAdmin.cfg
new file mode 100644
index 0000000000..8647b281a2
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin.cfg
@@ -0,0 +1,60 @@
+{this, "CosNotifyChannelAdmin::EventChannel"}.
+{from, "CosNotifyChannelAdmin::EventChannel"}.
+{{handle_info, "CosNotifyChannelAdmin::EventChannel"}, true}.
+{this, "CosNotifyChannelAdmin::EventChannelFactory"}.
+{from, "CosNotifyChannelAdmin::EventChannelFactory"}.
+{{handle_info, "CosNotifyChannelAdmin::EventChannelFactory"}, true}.
+{this, "CosNotifyChannelAdmin::SupplierAdmin"}.
+{from, "CosNotifyChannelAdmin::SupplierAdmin"}.
+{{handle_info, "CosNotifyChannelAdmin::SupplierAdmin"}, true}.
+{this, "CosNotifyChannelAdmin::ConsumerAdmin"}.
+{from, "CosNotifyChannelAdmin::ConsumerAdmin"}.
+{{handle_info, "CosNotifyChannelAdmin::ConsumerAdmin"}, true}.
+{this, "CosNotifyChannelAdmin::StructuredProxyPushSupplier"}.
+{from, "CosNotifyChannelAdmin::StructuredProxyPushSupplier"}.
+{{handle_info, "CosNotifyChannelAdmin::StructuredProxyPushSupplier"}, true}.
+{{impl, "CosNotifyChannelAdmin::StructuredProxyPushSupplier"}, "PusherSupplier_impl"}.
+{this, "CosNotifyChannelAdmin::StructuredProxyPullSupplier"}.
+{from, "CosNotifyChannelAdmin::StructuredProxyPullSupplier"}.
+{{handle_info, "CosNotifyChannelAdmin::StructuredProxyPullSupplier"}, true}.
+{{impl, "CosNotifyChannelAdmin::StructuredProxyPullSupplier"}, "PullerSupplier_impl"}.
+{this, "CosNotifyChannelAdmin::ProxyPushSupplier"}.
+{from, "CosNotifyChannelAdmin::ProxyPushSupplier"}.
+{{handle_info, "CosNotifyChannelAdmin::ProxyPushSupplier"}, true}.
+{{impl, "CosNotifyChannelAdmin::ProxyPushSupplier"}, "PusherSupplier_impl"}.
+{this, "CosNotifyChannelAdmin::ProxyPullSupplier"}.
+{from, "CosNotifyChannelAdmin::ProxyPullSupplier"}.
+{{handle_info, "CosNotifyChannelAdmin::ProxyPullSupplier"}, true}.
+{{impl, "CosNotifyChannelAdmin::ProxyPullSupplier"}, "PullerSupplier_impl"}.
+{this, "CosNotifyChannelAdmin::SequenceProxyPushSupplier"}.
+{from, "CosNotifyChannelAdmin::SequenceProxyPushSupplier"}.
+{{handle_info, "CosNotifyChannelAdmin::SequenceProxyPushSupplier"}, true}.
+{{impl, "CosNotifyChannelAdmin::SequenceProxyPushSupplier"}, "PusherSupplier_impl"}.
+{this, "CosNotifyChannelAdmin::SequenceProxyPullSupplier"}.
+{from, "CosNotifyChannelAdmin::SequenceProxyPullSupplier"}.
+{{handle_info, "CosNotifyChannelAdmin::SequenceProxyPullSupplier"}, true}.
+{{impl, "CosNotifyChannelAdmin::SequenceProxyPullSupplier"}, "PullerSupplier_impl"}.
+{this, "CosNotifyChannelAdmin::StructuredProxyPushConsumer"}.
+{from, "CosNotifyChannelAdmin::StructuredProxyPushConsumer"}.
+{{handle_info, "CosNotifyChannelAdmin::StructuredProxyPushConsumer"}, true}.
+{{impl, "CosNotifyChannelAdmin::StructuredProxyPushConsumer"}, "PusherConsumer_impl"}.
+{this, "CosNotifyChannelAdmin::StructuredProxyPullConsumer"}.
+{from, "CosNotifyChannelAdmin::StructuredProxyPullConsumer"}.
+{{handle_info, "CosNotifyChannelAdmin::StructuredProxyPullConsumer"}, true}.
+{{impl, "CosNotifyChannelAdmin::StructuredProxyPullConsumer"}, "PullerConsumer_impl"}.
+{this, "CosNotifyChannelAdmin::ProxyPushConsumer"}.
+{from, "CosNotifyChannelAdmin::ProxyPushConsumer"}.
+{{handle_info, "CosNotifyChannelAdmin::ProxyPushConsumer"}, true}.
+{{impl, "CosNotifyChannelAdmin::ProxyPushConsumer"}, "PusherConsumer_impl"}.
+{this, "CosNotifyChannelAdmin::ProxyPullConsumer"}.
+{from, "CosNotifyChannelAdmin::ProxyPullConsumer"}.
+{{handle_info, "CosNotifyChannelAdmin::ProxyPullConsumer"}, true}.
+{{impl, "CosNotifyChannelAdmin::ProxyPullConsumer"}, "PullerConsumer_impl"}.
+{this, "CosNotifyChannelAdmin::SequenceProxyPushConsumer"}.
+{from, "CosNotifyChannelAdmin::SequenceProxyPushConsumer"}.
+{{handle_info, "CosNotifyChannelAdmin::SequenceProxyPushConsumer"}, true}.
+{{impl, "CosNotifyChannelAdmin::SequenceProxyPushConsumer"}, "PusherConsumer_impl"}.
+{this, "CosNotifyChannelAdmin::SequenceProxyPullConsumer"}.
+{from, "CosNotifyChannelAdmin::SequenceProxyPullConsumer"}.
+{{handle_info, "CosNotifyChannelAdmin::SequenceProxyPullConsumer"}, true}.
+{{impl, "CosNotifyChannelAdmin::SequenceProxyPullConsumer"}, "PullerConsumer_impl"}.
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin.idl b/lib/cosNotification/src/CosNotifyChannelAdmin.idl
new file mode 100644
index 0000000000..b345ff5423
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin.idl
@@ -0,0 +1,275 @@
+#ifndef _COS_NOTIFYCHANNELADMIN_IDL_
+#define _COS_NOTIFYCHANNELADMIN_IDL_
+
+#pragma prefix "omg.org"
+
+#include<cosNotificationAppComm.idl>
+#include<CosNotifyFilter.idl>
+#include<CosNotifyComm.idl>
+#include<CosNotification.idl>
+
+module CosNotifyChannelAdmin {
+ exception ConnectionAlreadyActive {};
+ exception ConnectionAlreadyInactive {};
+ exception NotConnected {};
+ // Forward declarations
+ interface ConsumerAdmin;
+ interface SupplierAdmin;
+ interface EventChannel;
+ interface EventChannelFactory;
+
+ enum ProxyType {
+ PUSH_ANY,
+ PULL_ANY,
+ PUSH_STRUCTURED,
+ PULL_STRUCTURED,
+ PUSH_SEQUENCE,
+ PULL_SEQUENCE};
+
+ enum ObtainInfoMode {
+ ALL_NOW_UPDATES_OFF,
+ ALL_NOW_UPDATES_ON,
+ NONE_NOW_UPDATES_OFF,
+ NONE_NOW_UPDATES_ON};
+
+ interface ProxyConsumer : CosNotification::QoSAdmin, CosNotifyFilter::FilterAdmin {
+ readonly attribute ProxyType MyType;
+ readonly attribute SupplierAdmin MyAdmin;
+
+ CosNotification::EventTypeSeq obtain_subscription_types(in ObtainInfoMode mode);
+
+ void validate_event_qos (in CosNotification::QoSProperties required_qos,
+ out CosNotification::NamedPropertyRangeSeq available_qos)
+ raises (CosNotification::UnsupportedQoS);
+ }; // ProxyConsumer
+
+ interface ProxySupplier : CosNotification::QoSAdmin, CosNotifyFilter::FilterAdmin {
+ readonly attribute ProxyType MyType;
+ readonly attribute ConsumerAdmin MyAdmin;
+ attribute CosNotifyFilter::MappingFilter priority_filter;
+ attribute CosNotifyFilter::MappingFilter lifetime_filter;
+
+ CosNotification::EventTypeSeq obtain_offered_types(in ObtainInfoMode mode);
+
+ void validate_event_qos (in CosNotification::QoSProperties required_qos,
+ out CosNotification::NamedPropertyRangeSeq available_qos)
+ raises (CosNotification::UnsupportedQoS);
+ }; // ProxySupplier
+
+ interface ProxyPushConsumer : ProxyConsumer, CosNotifyComm::PushConsumer,
+ CosEventChannelAdmin::ProxyPushConsumer {
+ void connect_any_push_supplier (in CosEventComm::PushSupplier push_supplier)
+ raises(CosEventChannelAdmin::AlreadyConnected);
+ }; // ProxyPushConsumer
+
+ interface StructuredProxyPushConsumer : ProxyConsumer, CosNotifyComm::StructuredPushConsumer {
+ void connect_structured_push_supplier (in CosNotifyComm::StructuredPushSupplier push_supplier)
+ raises(CosEventChannelAdmin::AlreadyConnected);
+ }; // StructuredProxyPushConsumer
+
+ interface SequenceProxyPushConsumer : ProxyConsumer, CosNotifyComm::SequencePushConsumer {
+ void connect_sequence_push_supplier (in CosNotifyComm::SequencePushSupplier push_supplier)
+ raises(CosEventChannelAdmin::AlreadyConnected);
+ }; // SequenceProxyPushConsumer
+
+ interface ProxyPullSupplier : ProxySupplier, CosNotifyComm::PullSupplier,
+ CosEventChannelAdmin::ProxyPullSupplier, oe_CosNotificationComm::Event {
+ void connect_any_pull_consumer (in CosEventComm::PullConsumer pull_consumer)
+ raises(CosEventChannelAdmin::AlreadyConnected);
+ }; // ProxyPullSupplier
+
+ interface StructuredProxyPullSupplier : ProxySupplier, CosNotifyComm::StructuredPullSupplier,
+ oe_CosNotificationComm::Event {
+ void connect_structured_pull_consumer (in CosNotifyComm::StructuredPullConsumer pull_consumer)
+ raises(CosEventChannelAdmin::AlreadyConnected);
+ }; // StructuredProxyPullSupplier
+
+ interface SequenceProxyPullSupplier : ProxySupplier, CosNotifyComm::SequencePullSupplier,
+ oe_CosNotificationComm::Event {
+ void connect_sequence_pull_consumer (in CosNotifyComm::SequencePullConsumer pull_consumer)
+ raises(CosEventChannelAdmin::AlreadyConnected);
+ }; // SequenceProxyPullSupplier
+
+ interface ProxyPullConsumer : ProxyConsumer, CosNotifyComm::PullConsumer,
+ CosEventChannelAdmin::ProxyPullConsumer {
+ void connect_any_pull_supplier (in CosEventComm::PullSupplier pull_supplier)
+ raises(CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises(ConnectionAlreadyInactive, NotConnected);
+
+ void resume_connection()
+ raises(ConnectionAlreadyActive, NotConnected);
+ }; // ProxyPullConsumer
+
+ interface StructuredProxyPullConsumer : ProxyConsumer, CosNotifyComm::StructuredPullConsumer {
+ void connect_structured_pull_supplier (in CosNotifyComm::StructuredPullSupplier pull_supplier)
+ raises(CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises(ConnectionAlreadyInactive, NotConnected);
+
+ void resume_connection()
+ raises(ConnectionAlreadyActive, NotConnected);
+ }; // StructuredProxyPullConsumer
+
+ interface SequenceProxyPullConsumer : ProxyConsumer, CosNotifyComm::SequencePullConsumer {
+ void connect_sequence_pull_supplier (in CosNotifyComm::SequencePullSupplier pull_supplier)
+ raises(CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises(ConnectionAlreadyInactive, NotConnected);
+
+ void resume_connection()
+ raises(ConnectionAlreadyActive, NotConnected);
+ }; // SequenceProxyPullConsumer
+
+ interface ProxyPushSupplier : ProxySupplier, CosNotifyComm::PushSupplier,
+ CosEventChannelAdmin::ProxyPushSupplier, oe_CosNotificationComm::Event {
+ void connect_any_push_consumer (in CosEventComm::PushConsumer push_consumer)
+ raises(CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises(ConnectionAlreadyInactive, NotConnected);
+
+ void resume_connection()
+ raises(ConnectionAlreadyActive, NotConnected);
+ }; // ProxyPushSupplier
+
+ interface StructuredProxyPushSupplier : ProxySupplier, CosNotifyComm::StructuredPushSupplier,
+ oe_CosNotificationComm::Event {
+ void connect_structured_push_consumer (in CosNotifyComm::StructuredPushConsumer push_consumer)
+ raises(CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises(ConnectionAlreadyInactive, NotConnected);
+
+ void resume_connection()
+ raises(ConnectionAlreadyActive, NotConnected);
+ }; // StructuredProxyPushSupplier
+
+ interface SequenceProxyPushSupplier : ProxySupplier, CosNotifyComm::SequencePushSupplier,
+ oe_CosNotificationComm::Event {
+ void connect_sequence_push_consumer (in CosNotifyComm::SequencePushConsumer push_consumer)
+ raises(CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises(ConnectionAlreadyInactive, NotConnected);
+
+ void resume_connection()
+ raises(ConnectionAlreadyActive, NotConnected);
+ }; // SequenceProxyPushSupplier
+
+
+ typedef long ProxyID;
+ typedef sequence <ProxyID> ProxyIDSeq;
+
+ enum ClientType {
+ ANY_EVENT,
+ STRUCTURED_EVENT,
+ SEQUENCE_EVENT};
+
+ enum InterFilterGroupOperator {
+ AND_OP,
+ OR_OP };
+
+ typedef long AdminID;
+ typedef sequence<AdminID> AdminIDSeq;
+
+ exception AdminNotFound {};
+ exception ProxyNotFound {};
+
+ struct AdminLimit {
+ CosNotification::PropertyName name;
+ CosNotification::PropertyValue value;
+ };
+
+ exception AdminLimitExceeded { AdminLimit admin_property_err; };
+
+ interface ConsumerAdmin : CosNotification::QoSAdmin, CosNotifyComm::NotifySubscribe,
+ CosNotifyFilter::FilterAdmin, CosEventChannelAdmin::ConsumerAdmin,
+ oe_CosNotificationComm::Event {
+ readonly attribute AdminID MyID;
+ readonly attribute EventChannel MyChannel;
+ readonly attribute InterFilterGroupOperator MyOperator;
+ attribute CosNotifyFilter::MappingFilter priority_filter;
+ attribute CosNotifyFilter::MappingFilter lifetime_filter;
+ readonly attribute ProxyIDSeq pull_suppliers;
+ readonly attribute ProxyIDSeq push_suppliers;
+
+ ProxySupplier get_proxy_supplier (in ProxyID proxy_id)
+ raises (ProxyNotFound);
+
+ ProxySupplier obtain_notification_pull_supplier (in ClientType ctype, out ProxyID proxy_id)
+ raises (AdminLimitExceeded);
+
+ ProxySupplier obtain_notification_push_supplier (in ClientType ctype, out ProxyID proxy_id)
+ raises (AdminLimitExceeded);
+
+ void destroy();
+ }; // ConsumerAdmin
+
+ interface SupplierAdmin : CosNotification::QoSAdmin, CosNotifyComm::NotifyPublish,
+ CosNotifyFilter::FilterAdmin, CosEventChannelAdmin::SupplierAdmin ,
+ oe_CosNotificationComm::Event {
+ readonly attribute AdminID MyID;
+ readonly attribute EventChannel MyChannel;
+ readonly attribute InterFilterGroupOperator MyOperator;
+ readonly attribute ProxyIDSeq pull_consumers;
+ readonly attribute ProxyIDSeq push_consumers;
+
+ ProxyConsumer get_proxy_consumer (in ProxyID proxy_id)
+ raises (ProxyNotFound);
+
+ ProxyConsumer obtain_notification_pull_consumer (in ClientType ctype, out ProxyID proxy_id)
+ raises (AdminLimitExceeded);
+
+ ProxyConsumer obtain_notification_push_consumer (in ClientType ctype, out ProxyID proxy_id)
+ raises (AdminLimitExceeded);
+
+ void destroy();
+ }; // SupplierAdmin
+
+ interface EventChannel : CosNotification::QoSAdmin, CosNotification::AdminPropertiesAdmin,
+ CosEventChannelAdmin::EventChannel,
+ oe_CosNotificationComm::Event {
+ readonly attribute EventChannelFactory MyFactory;
+ readonly attribute ConsumerAdmin default_consumer_admin;
+ readonly attribute SupplierAdmin default_supplier_admin;
+ readonly attribute CosNotifyFilter::FilterFactory default_filter_factory;
+
+ ConsumerAdmin new_for_consumers(in InterFilterGroupOperator op, out AdminID id);
+
+ SupplierAdmin new_for_suppliers(in InterFilterGroupOperator op, out AdminID id);
+
+ ConsumerAdmin get_consumeradmin (in AdminID id)
+ raises (AdminNotFound);
+
+ SupplierAdmin get_supplieradmin (in AdminID id)
+ raises (AdminNotFound);
+
+ AdminIDSeq get_all_consumeradmins();
+
+ AdminIDSeq get_all_supplieradmins();
+ }; // EventChannel
+
+ typedef long ChannelID;
+ typedef sequence<ChannelID> ChannelIDSeq;
+ exception ChannelNotFound {};
+
+ interface EventChannelFactory {
+ EventChannel create_channel (in CosNotification::QoSProperties initial_qos,
+ in CosNotification::AdminProperties initial_admin,
+ out ChannelID id)
+ raises(CosNotification::UnsupportedQoS, CosNotification::UnsupportedAdmin);
+
+ ChannelIDSeq get_all_channels();
+
+ EventChannel get_event_channel (in ChannelID id)
+ raises (ChannelNotFound);
+ }; // EventChannelFactory
+}; // CosNotifyChannelAdmin
+
+
+#endif /* ifndef _COS_NOTIFYCHANNELADMIN_IDL_ */
+
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl
new file mode 100644
index 0000000000..5ac8c810ea
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin_impl.erl
@@ -0,0 +1,670 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-------------------------------------------------------------------
+%% File : CosNotifyChannelAdmin_ConsumerAdmin_impl.erl
+%% Purpose :
+%%-------------------------------------------------------------------
+
+-module('CosNotifyChannelAdmin_ConsumerAdmin_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::ConsumerAdmin -----------------
+-export([get_proxy_supplier/4,
+ obtain_notification_pull_supplier/4,
+ obtain_notification_push_supplier/4,
+ destroy/3]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotifyComm::NotifySubscribe ----------
+-export([subscription_change/5]).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin ------------
+-export([add_filter/4,
+ remove_filter/4,
+ get_filter/4,
+ get_all_filters/3,
+ remove_all_filters/3]).
+
+%%----- Inherit from CosEventChannelAdmin::ConsumerAdmin -----
+-export([obtain_push_supplier/3,
+ obtain_pull_supplier/3]).
+
+%% Attributes (external)
+-export(['_get_MyID'/3,
+ '_get_MyChannel'/3,
+ '_get_MyOperator'/3,
+ '_get_priority_filter'/3,
+ '_set_priority_filter'/4,
+ '_get_lifetime_filter'/3,
+ '_set_lifetime_filter'/4,
+ '_get_pull_suppliers'/3,
+ '_get_push_suppliers'/3]).
+
+%%--------------- Internal -----------------------------------
+%%----- Inherit from cosNotificationComm ---------------------
+-export([callAny/5,
+ callSeq/5]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {myId,
+ myChannel,
+ myChannelPid,
+ myOperator,
+ myFilters = [],
+ mySuppliers = [],
+ idCounter = 0,
+ priorityFilter,
+ lifetimeFilter,
+ etsR,
+ qosGlobal,
+ qosLocal,
+ options}).
+
+%% Data structures constructors
+-define(get_InitState(_MyID, _MyCh, _MyChP, _MyOp, _PFil, _LFil, _QoS, _LQS, _O),
+ #state{myId = _MyID,
+ myChannel = _MyCh,
+ myChannelPid = _MyChP,
+ myOperator = _MyOp,
+ priorityFilter = _PFil,
+ lifetimeFilter = _LFil,
+ qosGlobal = _QoS,
+ qosLocal = _LQS,
+ options = _O,
+ etsR = ets:new(oe_ets, [set, protected])}).
+
+%% Data structures selectors
+-define(get_PushSupplierIDs(S), find_ids(S#state.mySuppliers, pusher)).
+-define(get_PullSupplierIDs(S), find_ids(S#state.mySuppliers, puller)).
+-define(get_AllSuppliers(S), S#state.mySuppliers).
+-define(get_AllSupplierRefs(S), find_refs(S#state.mySuppliers)).
+-define(get_Supplier(S, I), find_obj(lists:keysearch(I,1,S#state.mySuppliers),
+ supplier)).
+
+-define(get_MyID(S), S#state.myId).
+-define(get_MyChannel(S), S#state.myChannel).
+-define(get_MyChannelPid(S), S#state.myChannelPid).
+-define(get_MyOperator(S), S#state.myOperator).
+-define(get_PrioFilter(S), S#state.priorityFilter).
+-define(get_LifeFilter(S), S#state.lifetimeFilter).
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+-define(get_Filter(S, I), find_obj(lists:keysearch(I, 1, S#state.myFilters),
+ filter)).
+-define(get_AllFilter(S), S#state.myFilters).
+-define(get_AllFilterID(S), find_ids(S#state.myFilters)).
+-define(get_Options(S), S#state.options).
+-define(get_IdCounter(S), S#state.idCounter).
+
+%% Data structures modifiers
+-define(set_PrioFilter(S,D), S#state{priorityFilter=D}).
+-define(set_LifeFilter(S,D), S#state{lifetimeFilter=D}).
+-define(set_LocalQoS(S,D), S#state{qosLocal=D}).
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+-define(add_PushSupplier(S,I,R,P),S#state{mySuppliers=[{I,R,P,pusher}|S#state.mySuppliers]}).
+-define(add_PullSupplier(S,I,R,P),S#state{mySuppliers=[{I,R,P,puller}|S#state.mySuppliers]}).
+-define(del_Supplier(S,I), S#state{mySuppliers=
+ lists:keydelete(I, 1,
+ S#state.mySuppliers)}).
+-define(del_SupplierRef(S,O), S#state{mySuppliers=
+ lists:keydelete(O, 2,
+ S#state.mySuppliers)}).
+-define(del_SupplierPid(S,P), S#state{mySuppliers=
+ lists:keydelete(P, 3,
+ S#state.mySuppliers)}).
+-define(add_Filter(S,I,O), S#state{myFilters=[{I,O}|S#state.myFilters]}).
+-define(del_Filter(S,I), S#state{myFilters=
+ delete_filter(lists:keydelete(I, 1,
+ S#state.myFilters),
+ S#state.myFilters)}).
+-define(del_AllFilter(S), S#state{myFilters=[]}).
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(
+ S#state.idCounter)).
+
+%% MISC
+-define(is_PersistentConnection(S),
+ ?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_PersistentEvent(S),
+ ?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_ANDOP(S), S#state.myOperator == 'AND_OP').
+
+%%----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%-----------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ case Info of
+ {'EXIT', Pid, Reason} when ?get_MyChannelPid(State) == Pid ->
+ ?DBG("PARENT CHANNEL: ~p TERMINATED.~n",[Reason]),
+ {stop, Reason, State};
+ {'EXIT', Pid, normal} ->
+ {noreply, ?del_SupplierPid(State, Pid)};
+ _Other ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyId, MyChannel, MyChannelPid, MyOperator, InitQoS, LQS, Options]) ->
+ process_flag(trap_exit, true),
+ PriorityFilter = corba:create_nil_objref(),
+ LifeTimeFilter = corba:create_nil_objref(),
+ {ok, ?get_InitState(MyId, MyChannel, MyChannelPid, MyOperator,
+ PriorityFilter, LifeTimeFilter, InitQoS, LQS, Options)}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_ConsumerAdmin attributes ------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyID'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyID'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyID(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyChannel'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyChannel'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyChannel(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyOperator'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyOperator'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyOperator(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_priority_filter'
+%% Type : read and write
+%% Returns :
+%%-----------------------------------------------------------
+'_get_priority_filter'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PrioFilter(State), State}.
+
+'_set_priority_filter'(_OE_THIS, _OE_FROM, State, PrioFilter) ->
+ {reply, ok, ?set_PrioFilter(State, PrioFilter)}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_lifetime_filter'
+%% Type : read and write
+%% Returns :
+%%-----------------------------------------------------------
+'_get_lifetime_filter'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_LifeFilter(State), State}.
+'_set_lifetime_filter'(_OE_THIS, _OE_FROM, State, LifeFilter) ->
+ {reply, ok, ?set_LifeFilter(State, LifeFilter)}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_pull_suppliers'
+%% Type : readonly
+%% Returns : ProxyIDSeq
+%%-----------------------------------------------------------
+'_get_pull_suppliers'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PullSupplierIDs(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_push_suppliers'
+%% Type : readonly
+%% Returns : ProxyIDSeq
+%%-----------------------------------------------------------
+'_get_push_suppliers'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PushSupplierIDs(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : get_proxy_supplier
+%% Arguments: ProxyID - unique identifier (long)
+%% Returns : ObjRef | {'EXCEPTION', #'ProxyNotFound'{}}
+%%-----------------------------------------------------------
+get_proxy_supplier(_OE_THIS, _OE_FROM, State, Proxy_id) ->
+ {reply, ?get_Supplier(State, Proxy_id), State}.
+
+%%----------------------------------------------------------%
+%% function : obtain_notification_pull_supplier
+%% Arguments: Ctype - 'ANY_EVENT' | 'STRUCTURED_EVENT' | 'SEQUENCE_EVENT'
+%% Returns : A Proxy of the requested type.
+%%-----------------------------------------------------------
+obtain_notification_pull_supplier(OE_THIS, _OE_FROM, State, Ctype) ->
+ %% Choose which module to use.
+ {Mod, Type} =
+ case Ctype of
+ 'ANY_EVENT' ->
+ {'CosNotifyChannelAdmin_ProxyPullSupplier', 'PULL_ANY'};
+ 'STRUCTURED_EVENT' ->
+ {'CosNotifyChannelAdmin_StructuredProxyPullSupplier', 'PULL_STRUCTURED'};
+ 'SEQUENCE_EVENT' ->
+ {'CosNotifyChannelAdmin_SequenceProxyPullSupplier', 'PULL_SEQUENCE'};
+ _ ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:"
+ "obtain_notification_pull_supplier(~p);~n"
+ "Incorrect enumerant",
+ [?LINE, Ctype], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end,
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case Mod:oe_create_link([Type, OE_THIS, self(), ?get_GlobalQoS(State),
+ ?get_LocalQoS(State), ?get_MyChannel(State),
+ ?get_Options(State), ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, PrRef} ->
+ ProxyID = ?new_Id(State),
+ NewState = ?add_PullSupplier(State, ProxyID, PrRef, Pid),
+ {reply, {PrRef, ProxyID}, ?set_IdCounter(NewState, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:"
+ "obtain_notification_pull_supplier();~n"
+ "Unable to create: ~p/~p~n"
+ "Reason: ~p", [?LINE, Mod, Type, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : obtain_notification_push_supplier
+%% Arguments: Ctype - 'ANY_EVENT' | 'STRUCTURED_EVENT' | 'SEQUENCE_EVENT'
+%% Returns : A Proxy of the requested type.
+%%-----------------------------------------------------------
+obtain_notification_push_supplier(OE_THIS, _OE_FROM, State, Ctype) ->
+ %% Choose which module to use.
+ {Mod, Type} =
+ case Ctype of
+ 'ANY_EVENT' ->
+ {'CosNotifyChannelAdmin_ProxyPushSupplier', 'PUSH_ANY'};
+ 'STRUCTURED_EVENT' ->
+ {'CosNotifyChannelAdmin_StructuredProxyPushSupplier', 'PUSH_STRUCTURED'};
+ 'SEQUENCE_EVENT' ->
+ {'CosNotifyChannelAdmin_SequenceProxyPushSupplier', 'PUSH_SEQUENCE'};
+ _ ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:"
+ "obtain_notification_push_supplier(~p);~n"
+ "Incorrect enumerant", [?LINE, Ctype], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end,
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case Mod:oe_create_link([Type, OE_THIS, self(), ?get_GlobalQoS(State),
+ ?get_LocalQoS(State), ?get_MyChannel(State),
+ ?get_Options(State), ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, PrRef} ->
+ ProxyID = ?new_Id(State),
+ NewState = ?add_PushSupplier(State, ProxyID, PrRef, Pid),
+ {reply, {PrRef, ProxyID}, ?set_IdCounter(NewState, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:obtain_notification_push_supplier();~n"
+ "Unable to create: ~p/~p~n"
+ "Reason: ~p",
+ [?LINE, Mod, Type, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+
+%%----------------------------------------------------------%
+%% function : destroy
+%% Arguments: -
+%% Returns : ok
+%%------------------------------------------------------------
+destroy(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, State}.
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {NewQoS, LQS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ admin, ?get_MyChannel(State),
+ ?get_AllSupplierRefs(State)),
+ {reply, ok, ?set_BothQoS(State, NewQoS, LQS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ admin, ?get_MyChannel(State),
+ ?get_AllSupplierRefs(State)),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotifyComm::NotifySubscribe ---------
+%%----------------------------------------------------------*
+%% function : subscription_change
+%% Arguments:
+%% Returns : ok |
+%% {'EXCEPTION', #'CosNotifyComm_InvalidEventType'{type}}
+%%-----------------------------------------------------------
+subscription_change(_OE_THIS, _OE_FROM, State, _Added, _Removed) ->
+ ?DBG("CALLBACK INFORMED: ~p ~p~n",[_Added, _Removed]),
+ {reply, ok, State}.
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin -----------
+%%----------------------------------------------------------%
+%% function : add_filter
+%% Arguments: Filter - CosNotifyFilter::Filter
+%% Returns : FilterID - long
+%%-----------------------------------------------------------
+add_filter(_OE_THIS, _OE_FROM, State, Filter) ->
+ 'CosNotification_Common':type_check(Filter, 'CosNotifyFilter_Filter'),
+ FilterID = ?new_Id(State),
+ NewState = ?set_IdCounter(State, FilterID),
+ {reply, FilterID, ?add_Filter(NewState, FilterID, Filter)}.
+
+%%----------------------------------------------------------%
+%% function : remove_filter
+%% Arguments: FilterID - long
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ok, ?del_Filter(State, FilterID)};
+remove_filter(_,_,_,_) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_filter
+%% Arguments: FilterID - long
+%% Returns : Filter - CosNotifyFilter::Filter |
+%% {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}
+%%-----------------------------------------------------------
+get_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ?get_Filter(State, FilterID), State};
+get_filter(_,_,_,_) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_filters
+%% Arguments: -
+%% Returns : Filter - CosNotifyFilter::FilterIDSeq
+%%-----------------------------------------------------------
+get_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_AllFilterID(State), State}.
+
+%%----------------------------------------------------------%
+%% function : remove_all_filters
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ok, ?del_AllFilter(State)}.
+
+%%----- Inherit from CosEventChannelAdmin::ConsumerAdmin ----
+%%----------------------------------------------------------%
+%% function : obtain_push_supplier
+%% Arguments: -
+%% Returns : ProxyPushSupplier
+%%-----------------------------------------------------------
+obtain_push_supplier(OE_THIS, _OE_FROM, State) ->
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case 'CosNotifyChannelAdmin_ProxyPushSupplier':oe_create_link(['PUSH_ANY', OE_THIS,
+ self(),
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_MyChannel(State),
+ ?get_Options(State),
+ ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, PrRef} ->
+ ProxyID = ?new_Id(State),
+ NewState = ?add_PushSupplier(State, ProxyID, PrRef, Pid),
+ {reply, PrRef, ?set_IdCounter(NewState, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:obtain_push_supplier();~n"
+ "Unable to create: CosNotifyChannelAdmin_ProxyPushSupplier~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : obtain_pull_supplier
+%% Arguments: -
+%% Returns : ProxyPullSupplier
+%%-----------------------------------------------------------
+obtain_pull_supplier(OE_THIS, _OE_FROM, State) ->
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case 'CosNotifyChannelAdmin_ProxyPullSupplier':oe_create_link(['PULL_ANY', OE_THIS,
+ self(),
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_MyChannel(State),
+ ?get_Options(State),
+ ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, PrRef} ->
+ ProxyID = ?new_Id(State),
+ NewState = ?add_PullSupplier(State, ProxyID, PrRef, Pid),
+ {reply, PrRef, ?set_IdCounter(NewState, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:obtain_pull_supplier();~n"
+ "Unable to create: CosNotifyChannelAdmin_ProxyPullSupplier~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+%% To match suppliers
+find_obj({value, {_,Obj,_,_}},_) -> Obj;
+%% To match filters
+find_obj({value, {_,Obj}},_) -> Obj;
+find_obj(_, supplier) -> {'EXCEPTION', #'CosNotifyChannelAdmin_ProxyNotFound'{}};
+find_obj(_, filter) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}.
+
+find_ids(List) ->
+ find_ids(List, [], false).
+find_ids(List, Type) ->
+ find_ids(List, [], Type).
+
+find_ids([], Acc, _) ->
+ Acc;
+find_ids([{I,_}|T], Acc, Type) ->
+ find_ids(T, [I|Acc], Type);
+find_ids([{I,_,_,Type}|T], Acc, Type) ->
+ find_ids(T, [I|Acc], Type);
+find_ids([{_I,_,_,_}|T], Acc, Type) ->
+ find_ids(T, Acc, Type);
+find_ids(What, _, _) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:find_ids();~n"
+ "Id corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+find_refs(List) ->
+ find_refs(List, []).
+
+find_refs([], Acc) ->
+ Acc;
+find_refs([{_,R,_,_}|T], Acc) ->
+ find_refs(T, [R|Acc]);
+find_refs(What, _) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:find_refs();~n"
+ "Reference corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%% Delete a single filter.
+%% The list do not differ, i.e., no filter removed, raise exception.
+delete_filter(List,List) -> corba:raise(#'CosNotifyFilter_FilterNotFound'{});
+delete_filter(List, _) -> List.
+
+
+%%-----------------------------------------------------------
+%% function : callSeq
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callSeq(_OE_THIS, OE_FROM, State, Events, _Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:filter_events(Events, ?get_AllFilter(State)) of
+ {[], _} when ?is_ANDOP(State) ->
+ %% Since AND it doesn't matter what the proxies 'think'. Done.
+ {noreply, State};
+ {[], Failed} ->
+ %% Is OR but the Proxy may allow the events; pass on.
+ forward(seq, State, Failed, 'MATCH');
+ {Passed, _} when ?is_ANDOP(State) ->
+ %% Since AND we only forward those who passed this objects filters.
+ forward(seq, State, Passed, 'MATCH');
+ {Passed, []} ->
+ %% Since OR we forward and tell the proxy to do no filtering.
+ forward(seq, State, Passed, 'MATCHED');
+ {Passed, Failed} ->
+ %% Since OR we forward both and instruct the proxy to check only
+ %% the ones that failed.
+ forward(seq, State, Passed, 'MATCHED'),
+ forward(seq, State, Failed, 'MATCH')
+ end.
+
+
+%%-----------------------------------------------------------
+%% function : callAny
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callAny(_OE_THIS, OE_FROM, State, Event, _Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:filter_events([Event], ?get_AllFilter(State)) of
+ {[], _} when ?is_ANDOP(State) ->
+ %% Since AND it doesn't matter what the proxies 'think'. Done.
+ {noreply, State};
+ {[], [Failed]} ->
+ %% Is OR but the Proxy may allow the event; pass on.
+ forward(any, State, Failed, 'MATCH');
+ {[Passed], _} when ?is_ANDOP(State) ->
+ %% Since AND we only forward those who passed this objects filters.
+ forward(any, State, Passed, 'MATCH');
+ {[Passed], _} ->
+ %% Since OR we forward and instruct the proxy to do no checks.
+ forward(any, State, Passed, 'MATCHED')
+ end.
+
+
+
+%% Forward events
+forward(Type, State, Event, Status) ->
+ forward(Type, ?get_AllSuppliers(State), State, Event, Status).
+forward(_, [], State, _, _) ->
+ {noreply, State};
+forward(any, [{_,H,_,_}|T], State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callAny(H, Event, Status) of
+ ok ->
+ ?DBG("CONSUMERADM FORWARD ANY: ~p~n",[Event]),
+ forward(any, T, State, Event, Status);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:forward();~n"
+ "Proxy no longer exists; dropping it: ~p",
+ [?LINE, H], ?DEBUG_LEVEL),
+ NewState = ?del_SupplierRef(State,H),
+ forward(any, T, NewState, Event, Status);
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:forward();~n"
+ "Proxy behaves badly: ~p/~p",
+ [?LINE, R, H], ?DEBUG_LEVEL),
+ forward(any, T, State, Event, Status);
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:forward();~n"
+ "Proxy behaves badly: ~p~n"
+ "Dropping it: ~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ NewState = ?del_SupplierRef(State, H),
+ forward(any, T, NewState, Event, Status)
+ end;
+forward(seq, [{_,H,_,_}|T], State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callSeq(H, Event, Status) of
+ ok ->
+ ?DBG("CONSUMERADM FORWARD SEQUENCE: ~p~n",[Event]),
+ forward(seq, T, State, Event, Status);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:forward();~n"
+ "Proxy no longer exists; dropping it: ~p",
+ [?LINE, H], ?DEBUG_LEVEL),
+ NewState = ?del_SupplierRef(State,H),
+ forward(seq, T, NewState, Event, Status);
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:forward();~n"
+ "Proxy behaves badly: ~p/~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ forward(seq, T, State, Event, Status);
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_ConsumerAdmin:forward();~n"
+ "Proxy behaves badly: ~p~n"
+ "Dropping it: ~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ NewState = ?del_SupplierRef(State, H),
+ forward(seq, T, NewState, Event, Status)
+ end.
+
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl
new file mode 100644
index 0000000000..872a786f92
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory_impl.erl
@@ -0,0 +1,142 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-------------------------------------------------------------------
+%% File : CosNotifyChannelAdmin_EventChannelFactory_impl.erl
+%% Purpose :
+%%-------------------------------------------------------------------
+
+-module('CosNotifyChannelAdmin_EventChannelFactory_impl').
+
+%%--------------- INCLUDES -----------------------------------
+%% Application files
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- IMPORTS ------------------------------------
+
+%%--------------- EXPORTS ------------------------------------
+%% External
+-export([create_channel/5,
+ get_all_channels/3,
+ get_event_channel/4]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {adminProp,
+ idCounter = 0,
+ options,
+ etsR,
+ server_options}).
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments: See gen_server documentation.
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?debug_print("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, normal} ->
+ ets:match_delete(State#state.etsR, {'_','_',Pid}),
+ {noreply, State};
+ _Other ->
+ ?debug_print("TERMINATED: ~p~n",[_Other]),
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init(Options) ->
+ process_flag(trap_exit, true),
+ SO = 'CosNotification_Common':get_option(server_options, Options, ?not_DEFAULT_SETTINGS),
+ {ok, #state{options = Options,
+ etsR = ets:new(oe_ets, [set, protected]),
+ server_options = SO}}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : create_channel
+%% Arguments: InitQoS
+%% InitAdmin
+%% Returns : Ch - Channel obj ref
+%% Id - Channel Id (out-type)
+%%-----------------------------------------------------------
+create_channel(OE_THIS, _OE_FROM, State, InitQoS, InitAdmin) ->
+ {QoS, LQoS} = 'CosNotification_Common':init_qos(InitQoS),
+ {IAdm, LAdm} = 'CosNotification_Common':init_adm(InitAdmin),
+ Id = 'CosNotification_Common':create_id(State#state.idCounter),
+ case 'CosNotifyChannelAdmin_EventChannel':oe_create_link([OE_THIS, QoS, IAdm,
+ LQoS, LAdm,
+ State#state.options],
+ [{sup_child, true}|State#state.server_options]) of
+ {ok, Pid, Ch} ->
+ ets:insert(State#state.etsR, {Id,Ch,Pid}),
+ {reply, {Ch, Id}, State#state{idCounter=Id}};
+ _ ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : get_all_channels
+%% Arguments: -
+%% Returns : ChannelIDSeq - List of alive channels created
+%% by this factory.
+%%-----------------------------------------------------------
+get_all_channels(_OE_THIS, _OE_FROM, State) ->
+ {reply, lists:flatten(ets:match(State#state.etsR, {'$1','_','_'})), State}.
+
+%%----------------------------------------------------------%
+%% function : get_event_channel
+%% Arguments: ChannelId
+%% Returns : ChannelRef | 'CosNotifyChannelAdmin_ChannelNotFound'
+%%-----------------------------------------------------------
+get_event_channel(_OE_THIS, _OE_FROM, State, Id) ->
+ {reply, find_obj(ets:lookup(State#state.etsR, Id)), State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj([]) -> {'EXCEPTION', #'CosNotifyChannelAdmin_ChannelNotFound'{}};
+find_obj([{_, Obj,_}]) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyChannelAdmin_ChannelNotFound'{}}.
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
new file mode 100644
index 0000000000..f37a97c4a7
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_EventChannel_impl.erl
@@ -0,0 +1,721 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-------------------------------------------------------------------
+%% File : CosNotifyChannelAdmin_EventChannel_impl.erl
+%% Purpose :
+%% Created : 28 Sep 1999
+%%-------------------------------------------------------------------
+
+-module('CosNotifyChannelAdmin_EventChannel_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::EventChannel ------------------
+-export([new_for_consumers/4,
+ new_for_suppliers/4,
+ get_consumeradmin/4,
+ get_supplieradmin/4,
+ get_all_consumeradmins/3,
+ get_all_supplieradmins/3]).
+
+%% Attributes (external)
+-export(['_get_MyFactory'/3,
+ '_get_default_consumer_admin'/3,
+ '_get_default_supplier_admin'/3,
+ '_get_default_filter_factory'/3]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotification::AdminPropertiesAdmin ---
+-export([get_admin/3,
+ set_admin/4]).
+
+%%----- Inherit from CosEventChannelAdmin::EventChannel ------
+-export([for_consumers/3,
+ for_suppliers/3,
+ destroy/3]).
+%%--------------- Internal -----------------------------------
+%%----- Inherit from cosNotificationComm ---------------------
+-export([callAny/5,
+ callSeq/5]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%% Data structures
+-record(state, {myFac,
+ myConsumers = [],
+ defConsumerAdmin,
+ defSupplierAdmin,
+ defConsumerAdminPid,
+ defSupplierAdminPid,
+ defFilterFac,
+ defFilterFacPid,
+ etsR,
+ qosLocal,
+ qosGlobal,
+ admGlobal,
+ options,
+ idCounter = 0,
+ 'MaxQueueLength',
+ 'MaxConsumers',
+ 'MaxSuppliers'}).
+%% Data structures constructors
+-define(get_InitState(My, Fil, FilPid, QoS, LQoS, GA, MQ, MC, MS, O),
+ #state{myFac = My,
+ defFilterFac = Fil,
+ defFilterFacPid = FilPid,
+ etsR = ets:new(oe_ets, [set, protected]),
+ qosLocal = LQoS,
+ qosGlobal = QoS,
+ admGlobal = GA,
+ options = O,
+ 'MaxQueueLength' = MQ,
+ 'MaxConsumers' = MC,
+ 'MaxSuppliers' = MS}).
+
+%% NOTE!!!
+%% When forwarding events, the objects we will contact is ONLY ConsumerAdmins!!
+%% Hence, we will store SupplierAdmins and ConsumerAdmins differently. SupplierAdmins
+%% we store in our ets-table while the ConsumerAdmins will be stored on the local
+%% State.
+
+%% Data structures selectors
+-define(get_supplierAdmins(S), [S#state.defSupplierAdmin|
+ lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_'}))]).
+-define(get_consumerAdmins(S), [{0, S#state.defConsumerAdmin,S#state.defConsumerAdminPid}
+ |S#state.myConsumers]).
+-define(get_allAdmins(S), [S#state.defSupplierAdmin,
+ S#state.defConsumerAdmin|
+ lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_'}))++
+ find_field(S#state.myConsumers, 2)]).
+-define(get_consumerAdmIDs(S), [0|find_field(S#state.myConsumers, 1)]).
+-define(get_supplierAdmIDs(S), [0|lists:flatten(ets:match(S#state.etsR,
+ {'$1','_','_'}))]).
+
+-define(get_supplierAdmin(S, I), find_obj(ets:lookup(S#state.etsR, I))).
+-define(get_consumerAdmin(S, I), find_obj(lists:keysearch(I,1,S#state.myConsumers))).
+-define(get_supplierAmount(S), ets:info(S#state.etsR, size)).
+-define(get_consumerAmount(S), length(S#state.myConsumers)).
+
+-define(get_MyFactory(S), S#state.myFac).
+-define(get_defConsumerAdm(S), S#state.defConsumerAdmin).
+-define(get_defSupplierAdm(S), S#state.defSupplierAdmin).
+-define(get_defConsumerAdmPid(S), S#state.defConsumerAdminPid).
+-define(get_defSupplierAdmPid(S), S#state.defSupplierAdminPid).
+-define(get_defFilterFac(S), S#state.defFilterFac).
+-define(get_defFilterFacPid(S), S#state.defFilterFacPid).
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+-define(get_GlobalAdm(S), S#state.admGlobal).
+-define(get_Options(S), S#state.options).
+-define(get_MaxQueueLength(S), S#state.'MaxQueueLength').
+-define(get_MaxConsumers(S), S#state.'MaxConsumers').
+-define(get_MaxSuppliers(S), S#state.'MaxSuppliers').
+-define(get_IdCounter(S), S#state.idCounter).
+
+%% Data structures modifiers
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+-define(set_GlobalAdm(S,D), S#state{admGlobal=D}).
+-define(set_AllAdminP(S,GD, MQ, MC, MS),
+ S#state{admGlobal=GD,'MaxQueueLength'=MQ,
+ 'MaxConsumers'=MC, 'MaxSuppliers'=MS}).
+-define(set_MaxQueueLength(S,D), S#state{'MaxQueueLength'=D}).
+-define(set_MaxConsumers(S,D), S#state{'MaxConsumers'=D}).
+-define(set_MaxSuppliers(S,D), S#state{'MaxSuppliers'=D}).
+-define(set_defConsumerAdm(S,D,P), S#state{defConsumerAdmin=D, defConsumerAdminPid=P}).
+-define(set_defSupplierAdm(S,D,P), S#state{defSupplierAdmin=D, defSupplierAdminPid=P}).
+-define(set_defFilterFac(S,D,P), S#state{defFilterFac=D, defFilterFacPid=P}).
+-define(add_supplierAdmin(S,I,O,P), ets:insert(S#state.etsR, {I,O,P})).
+-define(add_consumerAdmin(S,I,O,P), S#state{myConsumers= [{I,O,P}|S#state.myConsumers]}).
+-define(del_supplierAdmin(S,I), ets:delete(S#state.etsR, I)).
+-define(del_consumerAdmin(S,I), S#state{myConsumers=
+ lists:keydelete(I, 1,
+ S#state.myConsumers)}).
+-define(del_consumerAdminRef(S,O), S#state{myConsumers=
+ lists:keydelete(O, 2,
+ S#state.myConsumers)}).
+-define(del_AdminPid(S,P), delete_obj(S, P)).
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+%% MISC
+-define(is_UndefDefConsAdm(S), S#state.defConsumerAdmin == undefined).
+-define(is_UndefDefSuppAdm(S), S#state.defSupplierAdmin == undefined).
+-define(is_UndefDefFilterFac(S), S#state.defFilterFac == undefined).
+-define(is_PersistentConnection(S),
+ ?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_PersistentEvent(S),
+ ?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent).
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?DBG("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, _Reason} when ?get_defConsumerAdmPid(State) == Pid ->
+ {noreply, ?set_defConsumerAdm(State, undefined, undefined)};
+ {'EXIT', Pid, _Reason} when ?get_defSupplierAdmPid(State) == Pid ->
+ {noreply, ?set_defSupplierAdm(State, undefined, undefined)};
+ {'EXIT', Pid, _Reason} when ?get_defFilterFacPid(State) == Pid ->
+ {noreply, ?set_defFilterFac(State, undefined, undefined)};
+ {'EXIT', Pid, normal} ->
+ {noreply, ?del_AdminPid(State, Pid)};
+ _Other ->
+ ?DBG("TERMINATED: ~p~n",[_Other]),
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyFac, InitQoS, InitAdmin, LocalQoS, [MaxQ, MaxC, MaxS|_], Options]) ->
+ process_flag(trap_exit, true),
+ SO = 'CosNotification_Common':get_option(server_options, Options,
+ ?not_DEFAULT_SETTINGS),
+
+ ?DBG("CHANNEL INIT STATE:~n~p~n~p~n~p ~p ~p ~p~n~p~n",
+ [InitQoS, InitAdmin, LocalQoS,MaxQ, MaxC, MaxS, Options]),
+
+ %% Both default Admin:s have the unique id 0 (OMG spec, 98-11-01,
+ %% Notification p 148), hence, no need to create a unique id.
+ %% We don't have acces to OE_THIS in this stage so we cannot create the objects
+ %% now, even though the specification states that.
+ %% DefConAdm = 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([0],[]),
+ %% DefSupAdm = 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([0],[]),
+
+ case 'CosNotifyFilter_FilterFactory':oe_create_link([], [{sup_child, true}|SO]) of
+ {ok, Pid, DefFiFac} ->
+ {ok, ?get_InitState(MyFac, DefFiFac, Pid, InitQoS, LocalQoS,
+ InitAdmin, MaxQ, MaxC, MaxS, Options)};
+ Reason ->
+ {stop, Reason}
+ end.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_EventChannel attributes -------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyFactory'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyFactory'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyFactory(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_default_consumer_admin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_default_consumer_admin'(OE_THIS, _OE_FROM, State)
+ when ?is_UndefDefConsAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefConAdm} ->
+ {reply, DefConAdm, ?set_defConsumerAdm(State, DefConAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:_get_default_consumer_admin();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+'_get_default_consumer_admin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_defConsumerAdm(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_default_supplier_admin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_default_supplier_admin'(OE_THIS, _OE_FROM, State)
+ when ?is_UndefDefSuppAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefSupAdm} ->
+ {reply, DefSupAdm, ?set_defSupplierAdm(State, DefSupAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:_get_default_supplier_admin();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+'_get_default_supplier_admin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_defSupplierAdm(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_default_filter_factory'
+%% Type : readonly
+%% Returns :
+%%----------------------------------------------------------
+'_get_default_filter_factory'(_OE_THIS, _OE_FROM, State)
+ when ?is_UndefDefFilterFac(State) ->
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyFilter_FilterFactory':oe_create_link([], [{sup_child, true}|SO]) of
+ {ok, Pid, DefFiFac} ->
+ {reply, DefFiFac, ?set_defFilterFac(State, DefFiFac, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:_get_default_filter_factory();~n"
+ "Unable to create: CosNotifyChannelAdmin_FilterFactory.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+'_get_default_filter_factory'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_defFilterFac(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : new_for_consumers
+%% Arguments: Op - InterFilterGroupOperator: 'AND_OP' | 'OR_OP'
+%% Determines if the Admin:s proxy-children will
+%% use AND or OR when checking Filters.
+%% Returns : ConsAdm
+%% AdminId (out)
+%%-----------------------------------------------------------
+new_for_consumers(OE_THIS, _OE_FROM, State, Op) ->
+ is_admin_limit_reached(?get_MaxConsumers(State), ?get_consumerAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminCo} ->
+ %% Due to different storage, adding a new consumer is NOT done in the
+ %% same way as for suppliers.
+ NewState = ?add_consumerAdmin(State, AdminId, AdminCo, Pid),
+ {reply, {AdminCo, AdminId}, ?set_IdCounter(NewState, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:nef_for_consumers();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : new_for_suppliers
+%% Arguments: Op - InterFilterGroupOperator: 'AND_OP' | 'OR_OP'
+%% Determines if the Admin:s proxy-children will
+%% use AND or OR when checking Filters.
+%% Returns : SuppAdm
+%% AdminId (out)
+%%-----------------------------------------------------------
+new_for_suppliers(OE_THIS, _OE_FROM, State, Op) ->
+ is_admin_limit_reached(?get_MaxSuppliers(State), ?get_supplierAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminSu} ->
+ %% Due to different storage, adding a new supplier is NOT done in the
+ %% same way as for consumers.
+ ?add_supplierAdmin(State, AdminId, AdminSu, Pid),
+ {reply, {AdminSu, AdminId}, ?set_IdCounter(State, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:new_for_suppliers();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : get_consumeradmin
+%% Arguments: AdminId
+%% Returns : ConsAdmin
+%%-----------------------------------------------------------
+get_consumeradmin(OE_THIS, _OE_FROM, State, 0) when ?is_UndefDefConsAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefConAdm} ->
+ {reply, DefConAdm, ?set_defConsumerAdm(State, DefConAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_consumer_admin();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+get_consumeradmin(_OE_THIS, _OE_FROM, State, 0) ->
+ {reply, ?get_defConsumerAdm(State), State};
+get_consumeradmin(_OE_THIS, _OE_FROM, State, AdminId) when is_integer(AdminId) ->
+ {reply, ?get_consumerAdmin(State, AdminId), State};
+get_consumeradmin(_, _, _, What) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_consumeradmin(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_supplieradmin
+%% Arguments: AdminId
+%% Returns :
+%%-----------------------------------------------------------
+get_supplieradmin(OE_THIS, _OE_FROM, State, 0) when ?is_UndefDefSuppAdm(State) ->
+ Op = 'CosNotification_Common':get_option(filterOp, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([0, OE_THIS,
+ self(), Op,
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, DefSupAdm} ->
+ {reply, DefSupAdm, ?set_defSupplierAdm(State, DefSupAdm, Pid)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_supplieradmin();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+get_supplieradmin(_OE_THIS, _OE_FROM, State, 0) ->
+ {reply, ?get_defSupplierAdm(State), State};
+get_supplieradmin(_OE_THIS, _OE_FROM, State, AdminId) when is_integer(AdminId) ->
+ {reply, ?get_supplierAdmin(State, AdminId), State};
+get_supplieradmin(_, _, _, What) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:get_supplieradmin(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_consumeradmins
+%% Arguments: -
+%% Returns : AdminIDSeq - a list of all unique ID:s.
+%%-----------------------------------------------------------
+get_all_consumeradmins(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_consumerAdmIDs(State), State}.
+
+%%----------------------------------------------------------%
+%% function : get_all_supplieradmins
+%% Arguments: -
+%% Returns : AdminIDSeq - a list of all unique ID:s.
+%%-----------------------------------------------------------
+get_all_supplieradmins(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_supplierAdmIDs(State), State}.
+
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments: -
+%% Returns : CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {GQoS,LQoS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ channel, false,
+ ?get_allAdmins(State)),
+ {reply, ok, ?set_BothQoS(State, GQoS,LQoS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS} |
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ channel, false,
+ ?get_allAdmins(State)),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotification::AdminPropertiesAdmin --
+%%-----------------------------------------------------------%
+%% function : get_admin
+%% Arguments: -
+%% Returns : AdminProperties
+%%-----------------------------------------------------------
+get_admin(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalAdm(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_admin
+%% Arguments: Admin
+%% Returns :
+%%-----------------------------------------------------------
+set_admin(_OE_THIS, _OE_FROM, State, Admin) ->
+ {GAdm,[MaxQ, MaxC, MaxS|_]} =
+ 'CosNotification_Common':set_adm(Admin, ?get_GlobalAdm(State)),
+ {reply, ok, ?set_AllAdminP(State, GAdm, MaxQ, MaxC, MaxS)}.
+
+%%----- Inherit from CosEventChannelAdmin::EventChannel -----
+%%----------------------------------------------------------%
+%% function : for_consumers
+%% Arguments: -
+%% Returns : ConsAdm
+%%-----------------------------------------------------------
+for_consumers(OE_THIS, _OE_FROM, State) ->
+ is_admin_limit_reached(?get_MaxConsumers(State), ?get_consumerAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ConsumerAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), 'AND_OP',
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminCo} ->
+ %% Due to different storage, adding a new consumer is NOT done in the
+ %% same way as for suppliers.
+ NewState = ?add_consumerAdmin(State, AdminId, AdminCo, Pid),
+ {reply, AdminCo, ?set_IdCounter(NewState, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:for_consumers();~n"
+ "Unable to create: CosNotifyChannelAdmin_ConsumerAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : for_suppliers
+%% Arguments: -
+%% Returns : SuppAdm
+%%-----------------------------------------------------------
+for_suppliers(OE_THIS, _OE_FROM, State) ->
+ is_admin_limit_reached(?get_MaxSuppliers(State), ?get_supplierAmount(State)),
+ AdminId = ?new_Id(State),
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_SupplierAdmin':oe_create_link([AdminId, OE_THIS,
+ self(), 'AND_OP',
+ ?get_GlobalQoS(State),
+ ?get_LocalQoS(State),
+ ?get_Options(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, AdminSu} ->
+ %% Due to different storage, adding a new supplier is NOT done in the
+ %% same way as for consumers.
+ ?add_supplierAdmin(State, AdminId, AdminSu, Pid),
+ {reply, AdminSu, ?set_IdCounter(State, AdminId)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:for_suppliers();~n"
+ "Unable to create: CosNotifyChannelAdmin_SupplierAdmin.~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%-----------------------------------------------------------%
+%% function : destroy
+%% Arguments: -
+%% Returns : ok
+%%------------------------------------------------------------
+destroy(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj([]) -> {'EXCEPTION', #'CosNotifyChannelAdmin_AdminNotFound'{}};
+find_obj([{_, Obj,_}]) -> Obj;
+find_obj({value, {_, Obj,_}}) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyChannelAdmin_AdminNotFound'{}}.
+
+
+find_field(List, Field) ->
+ find_field(List, Field, []).
+
+find_field([], _, Acc) ->
+ Acc;
+find_field([{I,_,_}|T], 1, Acc) ->
+ find_field(T, 1, [I|Acc]);
+find_field([{_,O,_}|T], 2, Acc) ->
+ find_field(T, 2, [O|Acc]);
+% Left out for now to avoid dialyzer warning.
+%find_field([{_,_,P}|T], 3, Acc) ->
+% find_field(T, 3, [P|Acc]);
+find_field(What, _, _) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:find_field();~n"
+ "Data corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+delete_obj(State, Pid) ->
+ case ets:match_object(State#state.etsR, {'_', '_', Pid}) of
+ [] ->
+ State#state{myConsumers=lists:keydelete(Pid, 3, State#state.myConsumers)};
+ [{Id,_Obj,Pid}] ->
+ ets:delete(State#state.etsR, Id),
+ State
+ end.
+
+%% Test if we have reached limit for Admin objects.
+is_admin_limit_reached(0, _) ->
+ %% When set to zero it means that there is no limit.
+ ok;
+is_admin_limit_reached(Max, Current) when Current >= Max ->
+ %% The Current value do not include the default Admin objects, hence
+ %% we use >= instead of >.
+ corba:raise(#'IMP_LIMIT'{completion_status=?COMPLETED_NO});
+is_admin_limit_reached(_, _) ->
+ ok.
+
+%%-----------------------------------------------------------
+%% function : callSeq
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callSeq(_OE_THIS, OE_FROM, State, Event, Status) ->
+ corba:reply(OE_FROM, ok),
+ forward(seq, State, Event, Status).
+
+%%-----------------------------------------------------------
+%% function : callAny
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callAny(_OE_THIS, OE_FROM, State, Event, Status) ->
+ corba:reply(OE_FROM, ok),
+ forward(any, State, Event, Status).
+
+%% Forward events
+forward(Type, State, Event, Status) ->
+ forward(Type, ?get_consumerAdmins(State), State, Event, Status).
+
+forward(_, [], State, _, _) ->
+ {noreply, State};
+forward(Type, [{_,undefined,_}|T], State, Event, Status) ->
+ %% Match if no default objects associated.
+ forward(Type, T, State, Event, Status);
+forward(any, [{_,H,_}|T], State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callAny(H, Event, Status) of
+ ok ->
+ ?DBG("CHANNEL FORWARD ANY: ~p~n",[Event]),
+ forward(any, T, State, Event, Status);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin no longer exists; dropping it: ~p",
+ [?LINE, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State,H),
+ forward(any, T, NewState, Event, Status);
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p/~p",
+ [?LINE, R, H], ?DEBUG_LEVEL),
+ forward(any, T, State, Event, Status);
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p~n"
+ "Dropping it: ~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State, H),
+ forward(any, T, NewState, Event, Status)
+ end;
+forward(seq, [{_,H,_}|T], State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callSeq(H, Event, Status) of
+ ok ->
+ ?DBG("CHANNEL FORWARD SEQUENCE: ~p~n",[Event]),
+ forward(seq, T, State, Event, Status);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin no longer exists; dropping it: ~p",
+ [?LINE, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State,H),
+ forward(seq, T, NewState, Event, Status);
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p/~p",
+ [?LINE, R, H], ?DEBUG_LEVEL),
+ forward(seq, T, State, Event, Status);
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_EventChannel:forward();~n"
+ "Admin behaves badly: ~p~n"
+ "Dropping it: ~p", [?LINE, R, H], ?DEBUG_LEVEL),
+ NewState = ?del_consumerAdminRef(State,H),
+ forward(seq, T, NewState, Event, Status)
+ end.
+
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl b/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl
new file mode 100644
index 0000000000..1c3f3d8d0b
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin_impl.erl
@@ -0,0 +1,579 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%-------------------------------------------------------------------
+%% File : CosNotifyChannelAdmin_SupplierAdmin_impl.erl
+%% Purpose :
+%%-------------------------------------------------------------------
+
+-module('CosNotifyChannelAdmin_SupplierAdmin_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::SupplierAdmin -----------------
+-export([get_proxy_consumer/4,
+ obtain_notification_pull_consumer/4,
+ obtain_notification_push_consumer/4,
+ destroy/3]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotifyComm::NotifyPublish ------------
+-export([offer_change/5]).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin ------------
+-export([add_filter/4,
+ remove_filter/4,
+ get_filter/4,
+ get_all_filters/3,
+ remove_all_filters/3]).
+
+%%----- Inherit from CosEventChannelAdmin::SupplierAdmin -----
+-export([obtain_push_consumer/3,
+ obtain_pull_consumer/3]).
+
+%% Attributes (external)
+-export(['_get_MyID'/3,
+ '_get_MyChannel'/3,
+ '_get_MyOperator'/3,
+ '_get_pull_consumers'/3,
+ '_get_push_consumers'/3]).
+
+%%--------------- Internal -----------------------------------
+%%----- Inherit from cosNotificationComm ---------------------
+-export([callAny/5,
+ callSeq/5]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {myId,
+ myChannel,
+ myChannelPid,
+ myOperator,
+ myFilters = [],
+ idCounter = 0,
+ etsR,
+ qosGlobal,
+ qosLocal,
+ options}).
+
+%% Data structures constructors
+-define(get_InitState(_MyID, _MyCh, _MyChP, _MyOp, _QoS, _LQS, _O),
+ #state{myId = _MyID,
+ myChannel = _MyCh,
+ myChannelPid = _MyChP,
+ myOperator = _MyOp,
+ qosGlobal = _QoS,
+ qosLocal = _LQS,
+ options = _O,
+ etsR = ets:new(oe_ets, [set, protected])}).
+
+%% Data structures selectors
+-define(get_PushConsumers(S), lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_',pusher}))).
+-define(get_PullConsumers(S), lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_',puller}))).
+-define(get_AllConsumers(S), lists:flatten(ets:match(S#state.etsR,
+ {'_','$1','_','_'}))).
+-define(get_PushConsumerIDs(S), lists:flatten(ets:match(S#state.etsR,
+ {'$1','_','_',pusher}))).
+-define(get_PullConsumerIDs(S), lists:flatten(ets:match(S#state.etsR,
+ {'$1','_','_',puller}))).
+
+-define(get_Consumer(S, I), find_obj(ets:lookup(S#state.etsR, I), consumer)).
+
+-define(get_MyID(S), S#state.myId).
+-define(get_MyChannel(S), S#state.myChannel).
+-define(get_MyChannelPid(S), S#state.myChannelPid).
+-define(get_MyOperator(S), S#state.myOperator).
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+-define(get_Filter(S, I), find_obj(lists:keysearch(I, 1, S#state.myFilters),
+ filter)).
+-define(get_AllFilter(S), S#state.myFilters).
+-define(get_AllFilterID(S), find_ids(S#state.myFilters)).
+-define(get_Options(S), S#state.options).
+-define(get_IdCounter(S), S#state.idCounter).
+
+%% Data structures modifiers
+-define(set_LocalQoS(S,D), S#state{qosLocal=D}).
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+-define(add_PushConsumer(S,I,R,P),ets:insert(State#state.etsR, {I,R,P,pusher})).
+-define(add_PullConsumer(S,I,R,P),ets:insert(State#state.etsR, {I,R,P,puller})).
+-define(del_Consumer(S,I), ets:delete(S#state.etsR, I)).
+-define(del_ConsumerPid(S,P), ets:match_delete(S#state.etsR, {'_','_',P,'_'})).
+-define(add_Filter(S,I,O), S#state{myFilters=[{I,O}|S#state.myFilters]}).
+-define(del_Filter(S,I), S#state{myFilters=
+ delete_filter(lists:keydelete(I, 1,
+ S#state.myFilters),
+ S#state.myFilters)}).
+-define(del_AllFilter(S), S#state{myFilters=[]}).
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+
+%% MISC
+-define(is_PersistentEvent(S),
+ ?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_PersistentConnection(S),
+ ?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent).
+
+%%----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%-----------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ case Info of
+ {'EXIT', Pid, Reason} when ?get_MyChannelPid(State) == Pid ->
+ ?DBG("PARENT CHANNEL: ~p TERMINATED.~n",[Reason]),
+ {stop, Reason, State};
+ {'EXIT', Pid, normal} ->
+ ?del_ConsumerPid(State, Pid),
+ {noreply, State};
+ _Other ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyId, MyChannel, MyChannelPid, MyOperator, InitQoS, LQS, Options]) ->
+ process_flag(trap_exit, true),
+ {ok, ?get_InitState(MyId, MyChannel, MyChannelPid, MyOperator, InitQoS, LQS, Options)}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_ConsumerAdmin attributes ------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyID'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyID'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyID(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyChannel'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyChannel'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyChannel(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyOperator'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyOperator'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyOperator(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_pull_consumers'
+%% Type : readonly
+%% Returns : ProxyIDSeq
+%%-----------------------------------------------------------
+'_get_pull_consumers'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PullConsumerIDs(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_push_consumers'
+%% Type : readonly
+%% Returns : ProxyIDSeq
+%%-----------------------------------------------------------
+'_get_push_consumers'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PushConsumerIDs(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : get_proxy_consumer
+%% Arguments: ProxyId - unique identifier (long)
+%% Returns : ObjRef | {'EXCEPTION', #'ProxyNotFound'{}}
+%%-----------------------------------------------------------
+get_proxy_consumer(_OE_THIS, _OE_FROM, State, ProxyId) ->
+ {reply, ?get_Consumer(State, ProxyId), State}.
+
+%%----------------------------------------------------------%
+%% function : obtain_notification_pull_consumer
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+obtain_notification_pull_consumer(OE_THIS, _OE_FROM, State, Ctype) ->
+ %% Choose which module to use.
+ {Mod, Type} =
+ case Ctype of
+ 'ANY_EVENT' ->
+ {'CosNotifyChannelAdmin_ProxyPullConsumer', 'PULL_ANY'};
+ 'STRUCTURED_EVENT' ->
+ {'CosNotifyChannelAdmin_StructuredProxyPullConsumer', 'PULL_STRUCTURED'};
+ 'SEQUENCE_EVENT' ->
+ {'CosNotifyChannelAdmin_SequenceProxyPullConsumer', 'PULL_SEQUENCE'};
+ _ ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:"
+ "obtain_notification_pull_consumer(~p);~n"
+ "Incorrect enumerant",
+ [?LINE, Ctype], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end,
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch Mod:oe_create_link([Type, OE_THIS, self(), ?get_GlobalQoS(State),
+ ?get_LocalQoS(State), ?get_MyChannel(State),
+ ?get_Options(State), ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, Proxy} ->
+ ProxyID = ?new_Id(State),
+ ?add_PullConsumer(State, ProxyID, Proxy, Pid),
+ {reply, {Proxy, ProxyID}, ?set_IdCounter(State, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:"
+ "obtain_notification_pull_consumer();~n"
+ "Unable to create: ~p/~p~n"
+ "Reason: ~p", [?LINE, Mod, Type, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : obtain_notification_push_supplier
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+obtain_notification_push_consumer(OE_THIS, _OE_FROM, State, Ctype) ->
+ %% Choose which module to use.
+ {Mod, Type} =
+ case Ctype of
+ 'ANY_EVENT' ->
+ {'CosNotifyChannelAdmin_ProxyPushConsumer', 'PUSH_ANY'};
+ 'STRUCTURED_EVENT' ->
+ {'CosNotifyChannelAdmin_StructuredProxyPushConsumer', 'PUSH_STRUCTURED'};
+ 'SEQUENCE_EVENT' ->
+ {'CosNotifyChannelAdmin_SequenceProxyPushConsumer', 'PUSH_SEQUENCE'};
+ _ ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:"
+ "obtain_notification_push_consumer(~p);~n"
+ "Incorrect enumerant", [?LINE, Ctype], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end,
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch Mod:oe_create_link([Type, OE_THIS, self(), ?get_GlobalQoS(State),
+ ?get_LocalQoS(State), ?get_MyChannel(State),
+ ?get_Options(State), ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, Proxy} ->
+ ProxyID = ?new_Id(State),
+ ?add_PushConsumer(State, ProxyID, Proxy, Pid),
+ {reply, {Proxy, ProxyID}, ?set_IdCounter(State, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:"
+ "obtain_notification_push_consumer();~n"
+ "Unable to create: ~p/~p~n"
+ "Reason: ~p", [?LINE, Mod, Type, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : destroy
+%% Arguments: -
+%% Returns : ok
+%%------------------------------------------------------------
+destroy(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, State}.
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {NewQoS, LQS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ admin, ?get_MyChannel(State),
+ ?get_AllConsumers(State)),
+ {reply, ok, ?set_BothQoS(State, NewQoS, LQS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS}
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ admin, ?get_MyChannel(State),
+ ?get_AllConsumers(State)),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotifyComm::NotifyPublish -----------
+%%----------------------------------------------------------*
+%% function : offer_change
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+offer_change(_OE_THIS, _OE_FROM, State, _Added, _Removed) ->
+ {reply, ok, State}.
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin -----------
+%%----------------------------------------------------------%
+%% function : add_filter
+%% Arguments: Filter - CosNotifyFilter::Filter
+%% Returns : FilterID - long
+%%-----------------------------------------------------------
+add_filter(_OE_THIS, _OE_FROM, State, Filter) ->
+ 'CosNotification_Common':type_check(Filter, 'CosNotifyFilter_Filter'),
+ FilterID = ?new_Id(State),
+ NewState = ?set_IdCounter(State, FilterID),
+ {reply, FilterID, ?add_Filter(NewState, FilterID, Filter)}.
+
+%%----------------------------------------------------------%
+%% function : remove_filter
+%% Arguments: FilterID - long
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ok, ?del_Filter(State, FilterID)};
+remove_filter(_,_,_,What) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:remove_filter(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_filter
+%% Arguments: FilterID - long
+%% Returns : Filter - CosNotifyFilter::Filter |
+%% {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}
+%%-----------------------------------------------------------
+get_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ?get_Filter(State, FilterID), State};
+get_filter(_,_,_,What) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:get_filter(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_filters
+%% Arguments: -
+%% Returns : Filter - CosNotifyFilter::FilterIDSeq
+%%-----------------------------------------------------------
+get_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_AllFilterID(State), State}.
+
+%%----------------------------------------------------------%
+%% function : remove_all_filters
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ok, ?del_AllFilter(State)}.
+
+%%----- Inherit from CosEventChannelAdmin::SupplierAdmin ----
+%%----------------------------------------------------------%
+%% function : obtain_push_consumer
+%% Arguments: -
+%% Returns : ProxyPushConsumer
+%%-----------------------------------------------------------
+obtain_push_consumer(OE_THIS, _OE_FROM, State) ->
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ProxyPushConsumer':
+ oe_create_link(['PUSH_ANY', OE_THIS, self(), ?get_GlobalQoS(State),
+ ?get_LocalQoS(State), ?get_MyChannel(State),
+ ?get_Options(State), ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, Proxy} ->
+ ProxyID = ?new_Id(State),
+ ?add_PushConsumer(State, ProxyID, Proxy, Pid),
+ {reply, Proxy, ?set_IdCounter(State, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:obtain_push_consumer();~n"
+ "Unable to create: CosNotifyChannelAdmin_ProxyPushConsumer~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%----------------------------------------------------------%
+%% function : obtain_pull_consumer
+%% Arguments: -
+%% Returns : ProxyPullConsumer
+%%-----------------------------------------------------------
+obtain_pull_consumer(OE_THIS, _OE_FROM, State) ->
+ SO = 'CosNotification_Common':get_option(server_options, ?get_Options(State),
+ ?not_DEFAULT_SETTINGS),
+ case catch 'CosNotifyChannelAdmin_ProxyPullConsumer':
+ oe_create_link(['PULL_ANY', OE_THIS, self(), ?get_GlobalQoS(State),
+ ?get_LocalQoS(State), ?get_MyChannel(State),
+ ?get_Options(State), ?get_MyOperator(State)],
+ [{sup_child, true}|SO]) of
+ {ok, Pid, Proxy} ->
+ ProxyID = ?new_Id(State),
+ ?add_PullConsumer(State, ProxyID, Proxy, Pid),
+ {reply, Proxy, ?set_IdCounter(State, ProxyID)};
+ What ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:obtain_push_consumer();~n"
+ "Unable to create: CosNotifyChannelAdmin_ProxyPullConsumer~n"
+ "Reason: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj([], consumer) -> {'EXCEPTION', #'CosNotifyChannelAdmin_ProxyNotFound'{}};
+find_obj([], filter) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}};
+%% To match consumers
+find_obj([{_,Obj,_,_}],_) -> Obj;
+%% To match filters
+find_obj({value, {_,Obj}},_) -> Obj;
+find_obj(_,consumer) -> {'EXCEPTION', #'CosNotifyChannelAdmin_ProxyNotFound'{}};
+find_obj(_,filter) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}.
+
+find_ids(List) -> find_ids(List, []).
+find_ids([], Acc) -> Acc;
+find_ids([{I,_}|T], Acc) -> find_ids(T, [I|Acc]);
+find_ids(What, _) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:find_ids();~n"
+ "Id corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%% Delete a single filter.
+%% The list do not differ, i.e., no filter removed, raise exception.
+delete_filter(List,List) -> corba:raise(#'CosNotifyFilter_FilterNotFound'{});
+delete_filter(List, _) -> List.
+
+%%-----------------------------------------------------------
+%% function : callSeq
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callSeq(_OE_THIS, OE_FROM, State, Events, _Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:filter_events(Events, ?get_AllFilter(State)) of
+ {[], _} ->
+ {noreply, State};
+ {Passed, _} ->
+ forward(seq, State, Passed, 'MATCHED')
+ end.
+
+%%-----------------------------------------------------------
+%% function : callAny
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callAny(_OE_THIS, OE_FROM, State, Event, _Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:filter_events([Event], ?get_AllFilter(State)) of
+ {[], _} ->
+ {noreply, State};
+ {[Passed], _} ->
+ forward(any, State, Passed, 'MATCHED')
+ end.
+
+%% Forward events
+forward(any, State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callAny(?get_MyChannel(State),
+ Event, Status) of
+ ok ->
+ ?DBG("SUPPLIERADM FORWARD ANY: ~p~n",[Event]),
+ {noreply, State};
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:forward();~n"
+ "Channel no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ {stop, normal, State};
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:forward();~n"
+ "Channel respond incorrect: ~p~n"
+ "Dropping: ~p", [?LINE, R, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:forward();~n"
+ "Channel respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, R, Event], ?DEBUG_LEVEL),
+ {stop, normal, State}
+ end;
+forward(seq, State, Event, Status) ->
+ case catch oe_CosNotificationComm_Event:callSeq(?get_MyChannel(State),
+ Event, Status) of
+ ok ->
+ ?DBG("SUPPLIERADM FORWARD SEQUENCE: ~p~n",[Event]),
+ {noreply, State};
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:forward();~n"
+ "Channel no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ {stop, normal, State};
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:forward();~n"
+ "Channel respond incorrect: ~p~n"
+ "Dropping: ~p", [?LINE, R, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ R ->
+ orber:dbg("[~p] CosNotifyChannelAdmin_SupplierAdmin:forward();~n"
+ "Channel respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, R, Event], ?DEBUG_LEVEL),
+ {stop, normal, State}
+ end.
+
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotifyComm.cfg b/lib/cosNotification/src/CosNotifyComm.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyComm.cfg
diff --git a/lib/cosNotification/src/CosNotifyComm.idl b/lib/cosNotification/src/CosNotifyComm.idl
new file mode 100644
index 0000000000..f0386f0982
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyComm.idl
@@ -0,0 +1,83 @@
+#ifndef _COS_NOTIFYCOMM_IDL_
+#define _COS_NOTIFYCOMM_IDL_
+
+#pragma prefix "omg.org"
+
+
+#include<CosNotification.idl>
+
+module CosNotifyComm {
+ exception InvalidEventType { CosNotification::EventType type; };
+
+ interface NotifyPublish {
+ void offer_change (in CosNotification::EventTypeSeq added,
+ in CosNotification::EventTypeSeq removed)
+ raises (InvalidEventType);
+ }; // NotifyPublish
+
+ interface NotifySubscribe {
+ void subscription_change(in CosNotification::EventTypeSeq added,
+ in CosNotification::EventTypeSeq removed)
+ raises (InvalidEventType);
+ }; // NotifySubscribe
+
+ interface PushConsumer : NotifyPublish, CosEventComm::PushConsumer { }; // PushConsumer
+
+ interface PullConsumer : NotifyPublish, CosEventComm::PullConsumer { }; // PullConsumer
+
+ interface PullSupplier : NotifySubscribe, CosEventComm::PullSupplier { }; // PullSupplier
+
+ interface PushSupplier : NotifySubscribe, CosEventComm::PushSupplier { };
+
+ interface StructuredPushConsumer : NotifyPublish {
+ void push_structured_event(in CosNotification::StructuredEvent notification)
+ raises(CosEventComm::Disconnected);
+
+ void disconnect_structured_push_consumer();
+ }; // StructuredPushConsumer
+
+ interface StructuredPullConsumer : NotifyPublish {
+ void disconnect_structured_pull_consumer();
+ }; // StructuredPullConsumer
+
+ interface StructuredPullSupplier : NotifySubscribe {
+ CosNotification::StructuredEvent pull_structured_event()
+ raises(CosEventComm::Disconnected);
+
+ CosNotification::StructuredEvent try_pull_structured_event(out boolean has_event)
+ raises(CosEventComm::Disconnected);
+
+ void disconnect_structured_pull_supplier();
+ }; // StructuredPullSupplier
+
+ interface StructuredPushSupplier : NotifySubscribe {
+ void disconnect_structured_push_supplier();
+ }; // StructuredPushSupplier
+
+ interface SequencePushConsumer : NotifyPublish {
+ void push_structured_events(in CosNotification::EventBatch notifications)
+ raises(CosEventComm::Disconnected);
+
+ void disconnect_sequence_push_consumer();
+ }; // SequencePushConsumer
+
+ interface SequencePullConsumer : NotifyPublish {
+ void disconnect_sequence_pull_consumer();
+ }; // SequencePullConsumer
+
+ interface SequencePullSupplier : NotifySubscribe {
+ CosNotification::EventBatch pull_structured_events(in long max_number)
+ raises(CosEventComm::Disconnected);
+ CosNotification::EventBatch try_pull_structured_events(in long max_number, out boolean has_event)
+ raises(CosEventComm::Disconnected);
+
+ void disconnect_sequence_pull_supplier();
+ }; // SequencePullSupplier
+
+ interface SequencePushSupplier : NotifySubscribe {
+ void disconnect_sequence_push_supplier();
+ }; // SequencePushSupplier
+}; // CosNotifyComm
+
+#endif /* ifndef _COS_NOTIFYCOMM_IDL_ */
+
diff --git a/lib/cosNotification/src/CosNotifyFilter.cfg b/lib/cosNotification/src/CosNotifyFilter.cfg
new file mode 100644
index 0000000000..167550e0f5
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyFilter.cfg
@@ -0,0 +1,6 @@
+{this, "CosNotifyFilter::Filter"}.
+{{handle_info, "CosNotifyFilter::Filter"}, true}.
+{this, "CosNotifyFilter::MappingFilter"}.
+{{handle_info, "CosNotifyFilter::MappingFilter"}, true}.
+{this, "CosNotifyFilter::FilterFactory"}.
+{{handle_info, "CosNotifyFilter::FilterFactory"}, true}.
diff --git a/lib/cosNotification/src/CosNotifyFilter.idl b/lib/cosNotification/src/CosNotifyFilter.idl
new file mode 100644
index 0000000000..c6498ddcd0
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyFilter.idl
@@ -0,0 +1,140 @@
+#ifndef _COS_NOTIFYFILTER_IDL_
+#define _COS_NOTIFYFILTER_IDL_
+
+#pragma prefix "omg.org"
+
+#include<CosNotifyComm.idl>
+#include<CosNotification.idl>
+
+module CosNotifyFilter {
+ typedef long ConstraintID;
+ struct ConstraintExp {
+ CosNotification::EventTypeSeq event_types;
+ string constraint_expr;
+ };
+
+ typedef sequence<ConstraintID> ConstraintIDSeq;
+ typedef sequence<ConstraintExp> ConstraintExpSeq;
+ struct ConstraintInfo {
+ ConstraintExp constraint_expression;
+ ConstraintID constraint_id;
+ };
+ typedef sequence<ConstraintInfo> ConstraintInfoSeq;
+ struct MappingConstraintPair {
+ ConstraintExp constraint_expression;
+ any result_to_set;
+ };
+ typedef sequence<MappingConstraintPair> MappingConstraintPairSeq;
+ struct MappingConstraintInfo {
+ ConstraintExp constraint_expression;
+ ConstraintID constraint_id;
+ any value;
+ };
+ typedef sequence<MappingConstraintInfo> MappingConstraintInfoSeq;
+ typedef long CallbackID;
+ typedef sequence<CallbackID> CallbackIDSeq;
+ exception UnsupportedFilterableData {};
+ exception InvalidGrammar {};
+ exception InvalidConstraint {ConstraintExp constr;};
+ exception DuplicateConstraintID {ConstraintID id;};
+ exception ConstraintNotFound {ConstraintID id;};
+ exception CallbackNotFound {};
+ exception InvalidValue {ConstraintExp constr; any value;};
+ interface Filter {
+ readonly attribute string constraint_grammar;
+ ConstraintInfoSeq add_constraints (in ConstraintExpSeq constraint_list)
+ raises (InvalidConstraint);
+
+ void modify_constraints (in ConstraintIDSeq del_list,
+ in ConstraintInfoSeq modify_list)
+ raises (InvalidConstraint, ConstraintNotFound);
+
+ ConstraintInfoSeq get_constraints(in ConstraintIDSeq id_list)
+ raises (ConstraintNotFound);
+
+ ConstraintInfoSeq get_all_constraints();
+
+ void remove_all_constraints();
+ void destroy();
+ boolean match (in any filterable_data)
+ raises (UnsupportedFilterableData);
+
+ boolean match_structured (in CosNotification::StructuredEvent filterable_data)
+ raises (UnsupportedFilterableData);
+
+ boolean match_typed (in CosNotification::PropertySeq filterable_data)
+ raises (UnsupportedFilterableData);
+
+ CallbackID attach_callback (in CosNotifyComm::NotifySubscribe callback);
+
+ void detach_callback (in CallbackID callback)
+ raises ( CallbackNotFound );
+
+ CallbackIDSeq get_callbacks();
+ }; // Filter
+
+ interface MappingFilter {
+ readonly attribute string constraint_grammar;
+
+ readonly attribute CORBA::TypeCode value_type;
+
+ readonly attribute any default_value;
+
+ MappingConstraintInfoSeq add_mapping_constraints (in MappingConstraintPairSeq pair_list)
+ raises (InvalidConstraint, InvalidValue);
+
+ void modify_mapping_constraints (in ConstraintIDSeq del_list,
+ in MappingConstraintInfoSeq modify_list)
+ raises (InvalidConstraint, InvalidValue, ConstraintNotFound);
+
+ MappingConstraintInfoSeq get_mapping_constraints (in ConstraintIDSeq id_list)
+ raises (ConstraintNotFound);
+
+ MappingConstraintInfoSeq get_all_mapping_constraints();
+
+ void remove_all_mapping_constraints();
+
+ void destroy();
+
+ boolean match (in any filterable_data, out any result_to_set)
+ raises (UnsupportedFilterableData);
+
+ boolean match_structured (in CosNotification::StructuredEvent filterable_data, out any result_to_set)
+ raises (UnsupportedFilterableData);
+
+ boolean match_typed (in CosNotification::PropertySeq filterable_data, out any result_to_set)
+ raises (UnsupportedFilterableData);
+ }; // MappingFilter
+
+
+ interface FilterFactory {
+
+ Filter create_filter (in string constraint_grammar)
+ raises (InvalidGrammar);
+
+ MappingFilter create_mapping_filter (in string constraint_grammar, in any default_value)
+ raises(InvalidGrammar);
+ }; // FilterFactory
+
+ typedef long FilterID;
+ typedef sequence<FilterID> FilterIDSeq;
+ exception FilterNotFound {};
+
+ interface FilterAdmin {
+ FilterID add_filter (in Filter new_filter);
+
+ void remove_filter (in FilterID filter)
+ raises (FilterNotFound);
+
+ Filter get_filter (in FilterID filter)
+ raises (FilterNotFound);
+
+ FilterIDSeq get_all_filters();
+
+ void remove_all_filters();
+ }; // FilterAdmin
+}; // CosNotifyFilter
+
+
+#endif /* ifndef _COS_NOTIFYFILTER_IDL_ */
+
diff --git a/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl b/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl
new file mode 100644
index 0000000000..9a7b431513
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyFilter_FilterFactory_impl.erl
@@ -0,0 +1,125 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : CosNotifyFilter_FilterFactory_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('CosNotifyFilter_FilterFactory_impl').
+
+
+%%--------------- INCLUDES -----------------------------------
+%% Application files
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- IMPORTS ------------------------------------
+
+%%--------------- EXPORTS ------------------------------------
+%% External
+-export([create_filter/3,
+ create_mapping_filter/4]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {adminProp,
+ etsR,
+ options}).
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments: See gen_server documentation.
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(_Info, State) ->
+ ?debug_print("INFO: ~p DATA: ~p~n", [State, _Info]),
+ {noreply, State}.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init(Options) ->
+ process_flag(trap_exit, true),
+ {ok, #state{options = Options}}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : create_filter
+%% Arguments: InitGrammar - string()
+%% Returns : CosNotifyFilter::Filter |
+%% {'EXCEPTION', InvalidGrammar}
+%%-----------------------------------------------------------
+create_filter(OE_THIS, State, InitGrammar) ->
+ case lists:member(InitGrammar, ?not_SupportedGrammars) of
+ true ->
+ SO = 'CosNotification_Common':get_option(server_options, State#state.options,
+ ?not_DEFAULT_SETTINGS),
+ Fi='CosNotifyFilter_Filter':oe_create_link([OE_THIS, self(),
+ InitGrammar],
+ SO),
+ {reply, Fi, State};
+ _ ->
+ corba:raise(#'CosNotifyFilter_InvalidGrammar'{})
+ end.
+
+%%----------------------------------------------------------%
+%% function : create_mapping_filter
+%% Arguments: InitGrammar - string()
+%% Returns : CosNotifyFilter::Filter |
+%% {'EXCEPTION', InvalidGrammar}
+%%-----------------------------------------------------------
+create_mapping_filter(OE_THIS, State, InitGrammar, DefVal) ->
+ case lists:member(InitGrammar, ?not_SupportedGrammars) of
+ true ->
+ SO = 'CosNotification_Common':get_option(server_options, State#state.options,
+ ?not_DEFAULT_SETTINGS),
+ Fi='CosNotifyFilter_MappingFilter':oe_create_link([OE_THIS, self(),
+ InitGrammar, DefVal],
+ SO),
+ {reply, Fi, State};
+ _ ->
+ corba:raise(#'CosNotifyFilter_InvalidGrammar'{})
+ end.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl b/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl
new file mode 100644
index 0000000000..042e180170
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl
@@ -0,0 +1,670 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : CosNotifyFilter_Filter_impl.erl
+%% Purpose :
+%% Note : For an event to be forwarded it's sufficient that at least
+%% one of the constraints return 'true'.
+%% ALL functions in this module are internal. May NOT be used
+%% externally in ANY WAY; only CosNotification system modules.
+%%----------------------------------------------------------------------
+
+-module('CosNotifyFilter_Filter_impl').
+
+%%--------------- INCLUDES -----------------------------------
+%% Application files
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- IMPORTS ------------------------------------
+
+%%--------------- EXPORTS ------------------------------------
+%% External Attributes
+-export(['_get_constraint_grammar'/2]).
+%% External Functions
+-export([add_constraints/3,
+ modify_constraints/4,
+ get_constraints/3,
+ get_all_constraints/2,
+ remove_all_constraints/2,
+ destroy/2,
+ match/3,
+ match_structured/3,
+ match_typed/3,
+ attach_callback/3,
+ detach_callback/3,
+ get_callbacks/2]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%%######### MISC ##########
+-define(create_ConstraintInfo(_Types, _Con, _ID),
+ #'CosNotifyFilter_ConstraintInfo'{
+ constraint_expression =
+ #'CosNotifyFilter_ConstraintExp'{
+ event_types = _Types,
+ constraint_expr = _Con},
+ constraint_id = _ID
+ }).
+
+%%#### Data structures ####
+-record(state, {constraint_grammar,
+ constraints = [],
+ filters = [],
+ callbacks = [],
+ idCounter = 0,
+ filterFactory,
+ factoryPid,
+ etsR}).
+
+%% Data structures constructors
+-define(get_InitState(Fac, Pid, Gr),
+ #state{constraint_grammar=Gr,
+ filterFactory=Fac,
+ factoryPid=Pid,
+ etsR = ets:new(oe_ets, [bag, protected])}).
+
+%%------------------- Data structures selectors -------------------
+%% Grammar
+-define(get_Grammar(S), S#state.constraint_grammar).
+%% Callbacks
+% Left out for now to avoid dialyzer warning.
+%-define(get_Callback(S,I), find_obj(lists:keysearch(I, 1, S#state.callbacks),
+% callback)).
+-define(get_AllCallback(S), lists:map(fun({_V, C}) -> C end,
+ S#state.callbacks)).
+-define(get_AllCallbackID(S), lists:map(fun({V, _C}) -> V end,
+ S#state.callbacks)).
+%% ID:s
+-define(get_IdCounter(S), S#state.idCounter).
+
+%% Constraints
+-define(get_Constraint(S,I), find_obj(lists:keysearch(I, 1, S#state.constraints),
+ constraint)).
+-define(get_AllConstraints(S), lists:map(fun({I, C, _W, _WC, _K, T}) ->
+ ?create_ConstraintInfo(T, C, I)
+ end,
+ S#state.constraints)).
+-define(get_ConstraintAllData(S), S#state.constraints).
+-define(get_ConstraintData(S,I), lists:keysearch(I, 1, S#state.constraints)).
+-define(match_Type(S,I,ET), ets:lookup(S#state.etsR, {I, ET})).
+%% Parse Tree
+-define(get_ParseTree(S,K), find_obj(ets:lookup(S#state.etsR, K), tree)).
+
+%%------------------- Data structures modifiers -------------------
+%% Callbacks
+-define(del_Callback(S,I), S#state{callbacks =
+ delete_obj(lists:keydelete(I,1,
+ S#state.callbacks),
+ S#state.callbacks, callback)}).
+-define(del_AllCallbacks(S), S#state{callbacks=[]}).
+-define(add_Callback(S,V,C), S#state{idCounter=V,
+ callbacks = [{V,C}|S#state.callbacks]}).
+%% ID:s
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+
+%% Constraints
+-define(del_Constraint(S, I), match_delete(S, S#state.constraints, I)).
+-define(del_AllConstraints(S), clear_DB(S)).
+-define(add_Constraint(S,I,C,W,_WC,K,T), S#state{constraints =
+ [{I, C, W, _WC, K, T}|S#state.constraints]}).
+-define(set_Constraints(S,C), S#state{constraints = C}).
+
+-define(del_AllTypes(S), ets:match_delete(S#state.etsR, {'_','_',types})).
+-define(del_Type(S,I), ets:match_delete(S#state.etsR, {{I, '_'}, '_', types})).
+-define(add_Type(S,I,ET,K), ets:insert(S#state.etsR, {{I, ET}, K, types})).
+
+%% Parse Tree
+-define(add_ParseTree(S,K,T), ets:insert(S#state.etsR, {K, T, tree})).
+-define(del_ParseTree(S,K), ets:delete(S#state.etsR, K)).
+-define(del_AllParseTress(S), ets:match_delete(S#state.etsR, {'_','_',tree})).
+
+%%------------------- MISC ----------------------------------------
+-define(is_EmptyFilter(S), S#state.constraints==[]).
+
+-define(InfoSeq2EventTypeSeq(L), lists:flatten(
+ lists:map(fun(#'CosNotifyFilter_ConstraintInfo'
+ {constraint_expression=
+ #'CosNotifyFilter_ConstraintExp'
+ {event_types = ET}}) ->
+ ET
+ end,
+ L))).
+
+%%-----------------------------------------------------------%
+%% Function : handle_info, code_change
+%% Arguments: See gen_server documentation.
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?debug_print("INFO: ~p DATA: ~p~n", [State, Info]),
+ case Info of
+ {'EXIT', _Pid, _Reason} ->
+ {noreply, State};
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% Function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([FiFac, FacPid, ConstraintGr]) ->
+ process_flag(trap_exit, true),
+ {ok, ?get_InitState(FiFac, FacPid, ConstraintGr)}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%------- Exported external attributes ----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Function : '_get_constraint_grammar'/2
+%% Type : readonly
+%% Returns : Grammar - string()
+%%-----------------------------------------------------------
+'_get_constraint_grammar'(_OE_THIS, State) ->
+ {reply, ?get_Grammar(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Function : add_constraints/3
+%% Arguments: CL - CosNotifyFilter::ConstraintExpSeq
+%% Returns : CosNotifyFilter::ConstraintInfoSeq |
+%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint}
+%%-----------------------------------------------------------
+add_constraints(_OE_THIS, State, CL) ->
+ {NewState, Filters, Info, EventTSeq} = try_create_filters(State, CL),
+ NewState2=store_filters(NewState, Filters),
+ inform_callbacks(?get_AllCallback(NewState2), EventTSeq, []),
+ {reply, Info, NewState2}.
+
+%%----------------------------------------------------------%
+%% Function : modify_constraints/4
+%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq
+%% AddConstraintInfoSeq - CosNotifyFilter::ConstraintInfoSeq
+%% Returns : ok |
+%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} |
+%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound}
+%%-----------------------------------------------------------
+%% The OMG specification (TC Document telecom/98-11-01, chapter
+%% 3.2.1.3) states (concerning IDs):
+%%
+%% "If all input values supplied within a particular invocation
+%% of this operation are valid, then the specific constraints
+%% identified by the values contained in the first input parameter
+%% will be deleted from the list of those encapsulated by the target
+%% filter object."
+%%
+%% Hence, first we must check if all ID's exists before deleting.
+modify_constraints(_OE_THIS, State, IDs, AddConstraintInfoSeq) ->
+ %% The following functions are 'safe', i.e., they do not alter any data.
+ RemoveConstraintInfoSeq = lookup_constraints(IDs, State),
+ lookup_constraints(AddConstraintInfoSeq, State),
+ {NewState, Filters, _Info, AddedEventTSeq} =
+ try_create_filters(State, AddConstraintInfoSeq),
+ RemovedEventTSeq = ?InfoSeq2EventTypeSeq(RemoveConstraintInfoSeq),
+
+ %% We cannot change anything before our checks (see above). Hence,
+ %% do NOT move the following lines above this point.
+ NewState2 = delete_constraints(IDs, NewState),
+
+%% The OMG specification (TC Document telecom/98-11-01, chapter
+%% 3.2.1.3) states (concerning AddConstraintInfoSeq):
+%%
+%% "If all input values supplied within a particular invocation of this
+%% operation are valid, then the constraint expression associated with the
+%% already encapsulated constraint identified by the numeric value contained
+%% within each element of the input sequence will be modified to the new
+%% constraint expression that is contained within the same sequence element."
+%%
+%% This, our interpretation, implies that ALL previous data related
+%% to each unique ID should be removed and replaced by the new data.
+
+ NewState3 = delete_constraints(AddConstraintInfoSeq, NewState2),
+ NewState4 = store_filters(NewState3, Filters),
+ inform_callbacks(?get_AllCallback(NewState4),
+ AddedEventTSeq, RemovedEventTSeq),
+ {reply, ok, NewState4}.
+
+%%----------------------------------------------------------%
+%% Function : get_constraints/3
+%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq
+%% Returns : CosNotifyFilter::ConstraintInfoSeq |
+%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound}
+%%-----------------------------------------------------------
+get_constraints(_OE_THIS, State, IDs) ->
+ {reply, lookup_constraints(IDs, State), State}.
+
+%%----------------------------------------------------------%
+%% Function : get_all_constraints/2
+%% Arguments: -
+%% Returns : CosNotifyFilter::ConstraintInfoSeq
+%%-----------------------------------------------------------
+get_all_constraints(_OE_THIS, State) ->
+ {reply, ?get_AllConstraints(State), State}.
+
+%%----------------------------------------------------------%
+%% Function : remove_all_constraints/2
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_constraints(_OE_THIS, State) ->
+ {reply, ok, ?del_AllConstraints(State)}.
+
+%%----------------------------------------------------------%
+%% Function : destroy/2
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+destroy(_OE_THIS, State) ->
+ {stop, normal, ok, State}.
+
+%%----------------------------------------------------------%
+%% Function : match/3
+%% Arguments: Event - #any{}
+%% Returns : boolean() |
+%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
+%%-----------------------------------------------------------
+
+match(_OE_THIS, State, Event) when is_record(Event,'any'), ?is_EmptyFilter(State) ->
+ {reply, true, State};
+match(_OE_THIS, State, Event) when is_record(Event,'any') ->
+ match_any_event(State, Event, ?get_ConstraintAllData(State));
+match(_,_,What) ->
+ orber:dbg("[~p] CosNotifyFilter_Filter:match(~p);~n"
+ "Not an CORBA::Any", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% Function : match_structured/3
+%% Arguments: Event - CosNotification::StructuredEvent
+%% Returns : boolean() |
+%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
+%%-----------------------------------------------------------
+match_structured(_OE_THIS, State, Event) when
+ is_record(Event,'CosNotification_StructuredEvent') andalso ?is_EmptyFilter(State) ->
+ {reply, true, State};
+match_structured(_OE_THIS, State, Event) when
+ is_record(Event,'CosNotification_StructuredEvent') ->
+ match_str_event(State, Event, ?get_ConstraintAllData(State));
+match_structured(_,_,What) ->
+ orber:dbg("[~p] CosNotifyFilter_Filter:match_structured(~p);~n"
+ "Not a StructuredEvent", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------*
+%% Function : match_typed/3
+%% Arguments: Data - CosNotification::PropertySeq
+%% Returns : boolean() |
+%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
+%%-----------------------------------------------------------
+match_typed(_OE_THIS, _State, _Data) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% Function : attach_callback/3
+%% Arguments: CB - CosNotifyComm::NotifySubscribe
+%% Returns : ID - CosNotifyFilter::CallbackID
+%%-----------------------------------------------------------
+attach_callback(_OE_THIS, State, CB) ->
+ 'CosNotification_Common':type_check(CB, 'CosNotifyComm_NotifySubscribe'),
+ CBID = ?new_Id(State),
+ {reply, CBID, ?add_Callback(State, CBID, CB)}.
+
+%%----------------------------------------------------------%
+%% Function : detach_callback/3
+%% Arguments: ID - CosNotifyFilter::CallbackID
+%% Returns : ok | {'EXCEPTION', CosNotifyFilter::CallbackNotFound}
+%%-----------------------------------------------------------
+detach_callback(_OE_THIS, State, ID) when is_integer(ID) ->
+ {reply, ok, ?del_Callback(State, ID)};
+detach_callback(_,_,What) ->
+ orber:dbg("[~p] CosNotifyFilter_Filter:detach_callback(~p);~n"
+ "Not an integer", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% Function : get_callbacks/2
+%% Arguments: -
+%% Returns : CosNotifyFilter::CallbackIDSeq
+%%-----------------------------------------------------------
+get_callbacks(_OE_THIS, State) ->
+ {reply, ?get_AllCallbackID(State), State}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+%% To match callbacks
+find_obj({value, {_, Obj}},_) -> Obj;
+%% To match constraints
+find_obj({value, {Id, Con, _, _, _, Types}}, _) ->
+ ?create_ConstraintInfo(Types, Con, Id);
+find_obj([{_, Tree, tree}|_], tree) -> Tree;
+% Left out for now to avoid dialyzer warning.
+%find_obj(_,callback) -> {'EXCEPTION', #'CosNotifyFilter_CallbackNotFound'{}};
+find_obj(_,tree) -> undefined;
+find_obj(_,constraint) -> error.
+
+%% Delete a single object.
+delete_obj(List,List,callback) -> corba:raise(#'CosNotifyFilter_CallbackNotFound'{});
+delete_obj(List,_,_) -> List.
+
+%% Delete given object from list and all related objects in DB (parse tree and types).
+match_delete(State, Constraints, ID) ->
+ match_delete(State, Constraints, ID, []).
+match_delete(_, [], _, _) ->
+ error;
+match_delete(State, [{ID, _Con, _Which, _WC, Key, _Types}|T], ID, Acc) ->
+ ?del_Type(State, ID),
+ ?del_ParseTree(State, Key),
+ {ok, ?set_Constraints(State, Acc++T)};
+match_delete(State, [H|T], ID, Acc) ->
+ match_delete(State, T, ID, [H|Acc]).
+
+%% Remove all data related with constraints; for now, since no other data
+%% stored in DB, we do in a rather brutal way.
+clear_DB(State) ->
+ catch ets:delete(State#state.etsR),
+ State#state{etsR = ets:new(oe_ets, [bag, protected]), constraints=[]}.
+
+%% Given a list of Constrain IDs we want to find the related constraints.
+%% !!!!!! This function may not alter any data in DB in any way !!!!!!!!!!
+lookup_constraints(IDs, State) ->
+ lookup_constraints(IDs, State, []).
+lookup_constraints([], _State, Accum) ->
+ Accum;
+lookup_constraints([H|T], State, Accum)
+ when is_record(H, 'CosNotifyFilter_ConstraintInfo') ->
+ case ?get_Constraint(State, H#'CosNotifyFilter_ConstraintInfo'.constraint_id) of
+ error ->
+ corba:raise(#'CosNotifyFilter_ConstraintNotFound'
+ {id = H#'CosNotifyFilter_ConstraintInfo'.constraint_id});
+ _Con ->
+ %% We don't need to collect the result since the input already is of
+ %% the correct type, i.e., ConstraintInfoSeq
+ lookup_constraints(T, State, Accum)
+ end;
+lookup_constraints([H|T], State, Accum) when is_integer(H) ->
+ case ?get_Constraint(State,H) of
+ error ->
+ corba:raise(#'CosNotifyFilter_ConstraintNotFound'{id=H});
+ Con ->
+ lookup_constraints(T, State, [Con|Accum])
+ end;
+lookup_constraints(_, _, _) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%% Given a list of Constrain IDs we want to delet the related constraints.
+%% We need also to return the ConstraintInfoSeq described related to the
+%% given ID's.
+delete_constraints([], State) ->
+ State;
+delete_constraints([H|T], State)
+ when is_record(H, 'CosNotifyFilter_ConstraintInfo') ->
+ case catch ?del_Constraint(State,
+ H#'CosNotifyFilter_ConstraintInfo'.constraint_id) of
+ {ok, NewState} ->
+ delete_constraints(T, NewState);
+ Reason ->
+ orber:dbg("[~p] 'CosNotifyFilter_Filter':modify_constraints().~n"
+ "Unable to remove: ~p~n"
+ "Reason: ~p~n",
+ [?LINE, H, Reason], ?DEBUG_LEVEL),
+ delete_constraints(T, State)
+ end;
+delete_constraints([H|T], State) ->
+ case catch ?del_Constraint(State,H) of
+ {ok, NewState} ->
+ delete_constraints(T, NewState);
+ Reason ->
+ orber:dbg("[~p] 'CosNotifyFilter_Filter':modify_constraints().~n"
+ "Unable to remove: ~p~n"
+ "Reason: ~p~n",
+ [?LINE, H, Reason], ?DEBUG_LEVEL),
+ delete_constraints(T, State)
+ end.
+
+%% Inform all registered callbacks that the constraints have changed.
+%% Added and Removed must be a CosNotification::EventTypeSeq
+inform_callbacks([],_,_) ->
+ ok;
+inform_callbacks([H|T], Added, Removed) ->
+ case catch 'CosNotifyComm_NotifySubscribe':subscription_change(H, Added, Removed) of
+ ok ->
+ ?debug_print("INFORMED CALLBACK: ~p ADDED: ~p REMOVED: ~p",
+ [H, Added, Removed]),
+ inform_callbacks(T, Added, Removed);
+ Other ->
+ orber:dbg("[~p] 'CosNotifyComm_NotifySubscribe':subscription_change().~n"
+ "Unable to inform callback: ~p~n"
+ "Reason: ~p~n",
+ [?LINE, H, Other], ?DEBUG_LEVEL),
+ inform_callbacks(T, Added, Removed)
+ end.
+
+%%-----------------------------------------------------------
+%% Function : try_create_filters/2
+%% Arguments: CL - #'CosNotifyFilter_ConstraintExp'{
+%% event_types = [#'CosNotification_EventType'{
+%% domain_name = Str, type_name = Str}]
+%% constraint_expr = Str}
+%% Returns : {State, AccumList}
+%%-----------------------------------------------------------
+%% !!!!!! This function may not alter any data in DB in any way !!!!!!!!!!
+try_create_filters(State, CL) ->
+ try_create_filters(State, CL, [], [], []).
+try_create_filters(State, [], Accum, InfoSeq, EventTSeq) ->
+ {State, Accum, InfoSeq, EventTSeq};
+try_create_filters(State, [#'CosNotifyFilter_ConstraintExp'{event_types = Types,
+ constraint_expr = Con}|T],
+ Accum, InfoSeq, EventTSeq) ->
+ case catch cosNotification_Filter:create_filter(Con) of
+ {ok, Tree} ->
+ case catch cosNotification_Filter:check_types(Types) of
+ true ->
+ ID = ?new_Id(State),
+ Key = ?not_CreateDBKey,
+ NewETSeq = Types ++ EventTSeq,
+ try_create_filters(?set_IdCounter(State, ID), T,
+ [{ID, true, [], Key, Types, Con, Tree}|Accum],
+ [?create_ConstraintInfo(Types, Con, ID)|InfoSeq],
+ NewETSeq);
+ {ok, Which, WC} ->
+ ID = ?new_Id(State),
+ Key = ?not_CreateDBKey,
+ NewETSeq = Types ++ EventTSeq,
+ try_create_filters(?set_IdCounter(State, ID), T,
+ [{ID, Which, WC, Key, Types, Con, Tree}|Accum],
+ [?create_ConstraintInfo(Types, Con, ID)|InfoSeq],
+ NewETSeq);
+ _ ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+ _ ->
+ corba:raise(#'CosNotifyFilter_InvalidConstraint'
+ {constr = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con}})
+ end;
+try_create_filters(State, [#'CosNotifyFilter_ConstraintInfo'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con},
+ constraint_id=ID}|T], Accum, InfoSeq, EventTSeq) ->
+ case catch cosNotification_Filter:create_filter(Con) of
+ {ok, Tree} ->
+ case catch cosNotification_Filter:check_types(Types) of
+ true ->
+ Key = ?not_CreateDBKey,
+ NewETSeq = Types ++ EventTSeq,
+ try_create_filters(State, T,
+ [{ID, true, [], Key, Types, Con, Tree}|Accum],
+ [?create_ConstraintInfo(Types, Con, ID)|InfoSeq],
+ NewETSeq);
+ {ok, Which, WC} ->
+ Key = ?not_CreateDBKey,
+ NewETSeq = Types ++ EventTSeq,
+ try_create_filters(State, T,
+ [{ID, Which, WC, Key, Types, Con, Tree}|Accum],
+ [?create_ConstraintInfo(Types, Con, ID)|InfoSeq],
+ NewETSeq);
+ _ ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+ _ ->
+ corba:raise(#'CosNotifyFilter_InvalidConstraint'
+ {constr = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con}})
+ end;
+try_create_filters(_,_,_,_,_) ->
+ %% The list contained something else but ConstraintExp.
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%-----------------------------------------------------------
+%% Function : store_filters/4
+%% Arguments: Filters - a list of filters.
+%% Returns :
+%%-----------------------------------------------------------
+
+store_filters(State, []) ->
+ State;
+store_filters(State, [{ID, Which, WC, Key, Types, Con, Tree}|T]) ->
+ ?add_ParseTree(State, Key, Tree),
+ write_types(State, Types, ID, Key),
+ store_filters(?add_Constraint(State, ID, Con, Which, WC, Key, Types), T).
+
+
+write_types(_State, [],_, _) ->
+ ok;
+write_types(State, [EventType|T], ID, Key) ->
+ ?add_Type(State, ID, EventType, Key),
+ ?debug_print("FILTER: ~p ~p ~p~n", [ID, Key, EventType]),
+ write_types(State, T, ID, Key).
+
+%%-----------------------------------------------------------
+%% Function : match_any_event
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+match_any_event(State, _Event, []) ->
+ ?debug_print("FILTER REJECTED: ~p~n", [_Event]),
+ {reply, false, State};
+match_any_event(State, Event, [{_, _, _, _, Key, _}|T]) ->
+ case catch cosNotification_Filter:eval(?get_ParseTree(State,Key), Event) of
+ true ->
+ ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]),
+ {reply, true, State};
+ _ ->
+ match_any_event(State, Event, T)
+ end.
+
+
+%%-----------------------------------------------------------
+%% Function : match_str_event
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+
+match_str_event(State, _Event, []) ->
+ ?debug_print("FILTER REJECTED: ~p~n", [_Event]),
+ {reply, false, State};
+match_str_event(State, Event, [{ID, _Con, Which, WC, Key, _Types}|T]) ->
+ ET = ((Event#'CosNotification_StructuredEvent'.header)
+ #'CosNotification_EventHeader'.fixed_header)
+ #'CosNotification_FixedEventHeader'.event_type,
+ CheckList =
+ case Which of
+ both ->
+ [ET];
+ domain ->
+ [ET,
+ ET#'CosNotification_EventType'{type_name=""},
+ ET#'CosNotification_EventType'{type_name="*"}];
+ type ->
+ [ET,
+ ET#'CosNotification_EventType'{domain_name=""},
+ ET#'CosNotification_EventType'{domain_name="*"}];
+ _ ->
+ [ET,
+ ET#'CosNotification_EventType'{type_name=""},
+ ET#'CosNotification_EventType'{type_name="*"},
+ ET#'CosNotification_EventType'{domain_name=""},
+ ET#'CosNotification_EventType'{domain_name="*"}]
+ end,
+ case check_DB(State, ID, CheckList) of
+ false ->
+ %% No match, may have used wildcards, e.g., "dom*".
+ case catch cosNotification_Filter:match_types(
+ ET#'CosNotification_EventType'.domain_name,
+ ET#'CosNotification_EventType'.type_name,
+ WC) of
+ true ->
+ case catch cosNotification_Filter:eval(?get_ParseTree(State,Key),
+ Event) of
+ true ->
+ ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]),
+ {reply, true, State};
+ _ ->
+ match_str_event(State, Event, T)
+ end;
+ _->
+ match_str_event(State, Event, T)
+ end;
+ Key ->
+ case catch cosNotification_Filter:eval(?get_ParseTree(State,Key),
+ Event) of
+ true ->
+ ?debug_print("FILTER APPROVED: ~p~n", [Event]),
+ {reply, true, State};
+ _ ->
+ match_str_event(State, Event, T)
+ end
+ end.
+
+check_DB(_, _, []) ->
+ false;
+check_DB(State, ID, [H|T]) ->
+ case ?match_Type(State, ID, H) of
+ [] ->
+ check_DB(State, ID, T);
+ [{_, K, types}|_] ->
+ K
+ end.
+
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
+
diff --git a/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl b/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl
new file mode 100644
index 0000000000..f9103001f1
--- /dev/null
+++ b/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl
@@ -0,0 +1,578 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : CosNotifyFilter_MappingFilter_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('CosNotifyFilter_MappingFilter_impl').
+
+%%--------------- INCLUDES -----------------------------------
+%% Application files
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- IMPORTS ------------------------------------
+
+%%--------------- EXPORTS ------------------------------------
+%% External Attributes
+-export(['_get_constraint_grammar'/2,
+ '_get_value_type'/2,
+ '_get_default_value'/2]).
+%% External Functions
+-export([add_mapping_constraints/3,
+ modify_mapping_constraints/4,
+ get_mapping_constraints/3,
+ get_all_mapping_constraints/2,
+ remove_all_mapping_constraints/2,
+ destroy/2,
+ match/3,
+ match_structured/3,
+ match_typed/3]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%%######### MISC ##########
+-define(create_MappingInfo(_Types, _Con, _ID, _A),
+ #'CosNotifyFilter_MappingConstraintInfo'{
+ constraint_expression =
+ #'CosNotifyFilter_ConstraintExp'{
+ event_types = _Types,
+ constraint_expr = _Con},
+ constraint_id = _ID,
+ value = _A
+ }).
+%%#### Data structures ####
+-record(state, {constraint_grammar,
+ value,
+ typeC,
+ constraints = [],
+ filters = [],
+ idCounter = 0,
+ filterFactory,
+ factoryPid,
+ etsR}).
+
+%% Data structures constructors
+-define(get_InitState(Gr, DVal, FF, FP),
+ #state{constraint_grammar=Gr,
+ value = DVal,
+ typeC = any:get_typecode(DVal),
+ filterFactory = FF,
+ factoryPid = FP,
+ etsR = ets:new(oe_ets, [bag, protected])}).
+
+%%------------------- Data structures selectors -------------------
+%% Attributes
+-define(get_Grammar(S), S#state.constraint_grammar).
+-define(get_DefVal(S), S#state.value).
+-define(get_DefTC(S), S#state.typeC).
+-define(get_DefAny(S), S#state.value).
+
+%% ID:s
+-define(get_IdCounter(S), S#state.idCounter).
+
+%% Constraints
+-define(get_Constraint(S,I), find_obj(lists:keysearch(I, 1, S#state.constraints),
+ constraint)).
+-define(get_AllConstraints(S), lists:map(fun({I, C, _W, _WC, _K, T, A}) ->
+ ?create_MappingInfo(T, C, I, A)
+ end,
+ S#state.constraints)).
+-define(get_ConstraintAllData(S), S#state.constraints).
+-define(get_ConstraintData(S,I), lists:keysearch(I, 1, S#state.constraints)).
+-define(match_Type(S,I,ET), ets:lookup(S#state.etsR, {I, ET})).
+%% Parse Tree
+-define(get_ParseTree(S,K), find_obj(ets:lookup(S#state.etsR, K), tree)).
+
+%%------------------- Data structures modifiers -------------------
+%% ID:s
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+
+%% Constraints
+-define(del_Constraint(S, I), match_delete(S, S#state.constraints, I)).
+-define(del_AllConstraints(S), clear_DB(S)).
+-define(add_Constraint(S,I,C,W,_WC,K,T,A), S#state{constraints =
+ [{I, C, W, _WC, K, T, A}|S#state.constraints]}).
+-define(set_Constraints(S,C), S#state{constraints = C}).
+
+-define(del_AllTypes(S), ets:match_delete(S#state.etsR, {'_','_',types})).
+-define(del_Type(S,I), ets:match_delete(S#state.etsR, {{I, '_'}, '_', types})).
+-define(add_Type(S,I,ET,K), ets:insert(S#state.etsR, {{I, ET}, K, types})).
+
+%% Parse Tree
+-define(add_ParseTree(S,K,T), ets:insert(S#state.etsR, {K, T, tree})).
+-define(del_ParseTree(S,K), ets:delete(S#state.etsR, K)).
+-define(del_AllParseTress(S), ets:match_delete(S#state.etsR, {'_','_',tree})).
+
+%%------------------- MISC ----------------------------------------
+-define(is_EmptyFilter(S), S#state.constraints==[]).
+-define(is_EqualType(S,T), S#state.typeC==any:get_typecode(T)).
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments: See gen_server documentation.
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?debug_print("INFO: ~p DATA: ~p~n", [State, Info]),
+ case Info of
+ {'EXIT', _Pid, _Reason} ->
+ {noreply, State};
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([FiFac, FacPid, InitGr, DefVal]) ->
+ process_flag(trap_exit, true),
+ {ok, ?get_InitState(InitGr, DefVal, FiFac, FacPid)}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------
+%%------- Exported external attributes ----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Function : '_get_constraint_grammar'/2
+%% Type : readonly
+%% Returns : string()
+%%-----------------------------------------------------------
+'_get_constraint_grammar'(_OE_THIS, State) ->
+ {reply, ?get_Grammar(State), State}.
+%%----------------------------------------------------------%
+%% Function : '_get_value_type'/2
+%% Type : readonly
+%% Returns : CORBA::TypeCode
+%%-----------------------------------------------------------
+'_get_value_type'(_OE_THIS, State) ->
+ {reply, ?get_DefTC(State), State}.
+%%----------------------------------------------------------%
+%% Function : '_get_default_value'/2
+%% Type : readonly
+%% Returns : #any{}
+%%-----------------------------------------------------------
+'_get_default_value'(_OE_THIS, State) ->
+ {reply, ?get_DefVal(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Function : add_mapping_constraints/3
+%% Arguments: Pairs - CosNotifyFilter::MappingConstraintPairSeq
+%% Returns : CosNotifyFilter::MappingConstraintInfoSeq |
+%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} |
+%% {'EXCEPTION', CosNotifyFilter::InvalidValue}
+%%-----------------------------------------------------------
+add_mapping_constraints(_OE_THIS, State, Pairs) ->
+ {NewState, Filters, Info} = try_create_filters(State, Pairs),
+ NewState2=store_filters(NewState, Filters),
+ {reply, Info, NewState2}.
+
+%%----------------------------------------------------------%
+%% Function : modify_mapping_constraints/4
+%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq
+%% Info - CosNotifyFilter::MappingConstraintInfoSeq
+%% Returns : ok |
+%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} |
+%% {'EXCEPTION', CosNotifyFilter::InvalidValue} |
+%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound}
+%%-----------------------------------------------------------
+modify_mapping_constraints(_OE_THIS, State, IDs, InfoSeq) ->
+ lookup_constraints(IDs, State),
+ lookup_constraints(InfoSeq, State),
+ {NewState, Filters, _Info} = try_create_filters(State, InfoSeq),
+
+ %% We cannot change anything before our checks (see above). Hence,
+ %% do NOT move the following lines above this point.
+
+ NewState2 = delete_constraints(IDs, NewState),
+ NewState3 = delete_constraints(InfoSeq, NewState2),
+ NewState4 = store_filters(NewState3, Filters),
+ {reply, ok, NewState4}.
+
+%%----------------------------------------------------------%
+%% Function : get_mapping_constraints/3
+%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq
+%% Returns : CosNotifyFilter::MappingConstraintInfoSeq |
+%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound}
+%%-----------------------------------------------------------
+get_mapping_constraints(_OE_THIS, State, IDs) ->
+ {reply, lookup_constraints(IDs, State), State}.
+
+%%----------------------------------------------------------%
+%% Function : get_all_mapping_constraints/2
+%% Arguments: -
+%% Returns : CosNotifyFilter::MappingConstraintInfoSeq
+%%-----------------------------------------------------------
+get_all_mapping_constraints(_OE_THIS, State) ->
+ {reply, ?get_AllConstraints(State), State}.
+
+%%----------------------------------------------------------%
+%% Function : remove_all_mapping_constraints/2
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_mapping_constraints(_OE_THIS, State) ->
+ {reply, ok, ?del_AllConstraints(State)}.
+
+%%----------------------------------------------------------%
+%% Function : destroy/2
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+destroy(_OE_THIS, State) ->
+ {stop, normal, ok, State}.
+
+%%----------------------------------------------------------%
+%% Function : match/3
+%% Arguments: Event - #any{}
+%% Returns : boolean(), #any{} (out-type) |
+%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
+%%-----------------------------------------------------------
+match(_OE_THIS, State, Event) when is_record(Event,'any') andalso ?is_EmptyFilter(State) ->
+ {reply, {false, ?get_DefAny(State)}, State};
+match(_OE_THIS, State, Event) when is_record(Event,'any') ->
+ match_any_event(State, Event, ?get_ConstraintAllData(State));
+match(_,_,_) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+
+%%----------------------------------------------------------%
+%% Function : match_structured/3
+%% Arguments: Event - CosNotification::StructuredEvent
+%% Returns : boolean(), #any{} (out-type) |
+%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
+%%-----------------------------------------------------------
+match_structured(_OE_THIS, State, Event) when
+ is_record(Event,'CosNotification_StructuredEvent') andalso ?is_EmptyFilter(State) ->
+ {reply, {false, ?get_DefAny(State)}, State};
+match_structured(_OE_THIS, State, Event) when
+ is_record(Event,'CosNotification_StructuredEvent') ->
+ match_str_event(State, Event, ?get_ConstraintAllData(State));
+match_structured(_,_,_) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------*
+%% Function : match_typed/3
+%% Arguments: Data - CosNotification::PropertySeq
+%% Returns : boolean() , #any{} (out-type) |
+%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData}
+%%-----------------------------------------------------------
+match_typed(_OE_THIS, _State, _Data) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}).
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+%% To match constraints
+find_obj({value, {Id, Con, _, _, _, Types, Any}}, _) ->
+ ?create_MappingInfo(Types, Con, Id, Any);
+find_obj([{_, Tree, tree}|_], tree) -> Tree;
+find_obj(_,tree) -> undefined;
+find_obj(_,constraint) -> error.
+
+%% Delete given object from list and all related objects in DB (parse tree and types).
+match_delete(State, Constraints, ID) ->
+ match_delete(State, Constraints, ID, []).
+match_delete(_, [], _, _) ->
+ error;
+match_delete(State, [{ID, _Con, _Which, _WC, Key, _Types, _Any}|T], ID, Acc) ->
+ ?del_Type(State, ID),
+ ?del_ParseTree(State, Key),
+ {ok, ?set_Constraints(State, Acc++T)};
+match_delete(State, [H|T], ID, Acc) ->
+ match_delete(State, T, ID, [H|Acc]).
+
+%% Remove all data related with constraints; for now, since no other data
+%% stored in DB, we do in a rather brutal way.
+clear_DB(State) ->
+ catch ets:delete(State#state.etsR),
+ State#state{etsR = ets:new(oe_ets, [bag, protected]), constraints=[]}.
+
+%% Given a list of Constrain IDs we want to find the related constraints.
+%% !!!!!! This function may not alter any data in DB in any way !!!!!!!!!!
+lookup_constraints(IDs, State) ->
+ lookup_constraints(IDs, State, []).
+lookup_constraints([], _State, Accum) ->
+ Accum;
+lookup_constraints([H|T], State, Accum)
+ when is_record(H, 'CosNotifyFilter_MappingConstraintInfo') ->
+ case ?get_Constraint(State, H#'CosNotifyFilter_MappingConstraintInfo'.constraint_id) of
+ error ->
+ corba:raise(#'CosNotifyFilter_ConstraintNotFound'
+ {id = H#'CosNotifyFilter_MappingConstraintInfo'.constraint_id});
+ _Con ->
+ %% We don't need to collect the result since the input already is of
+ %% the correct type, i.e., ConstraintInfoSeq
+ lookup_constraints(T, State, Accum)
+ end;
+lookup_constraints([H|T], State, Accum) when is_integer(H) ->
+ case ?get_Constraint(State,H) of
+ error ->
+ corba:raise(#'CosNotifyFilter_ConstraintNotFound'{id=H});
+ Con ->
+ lookup_constraints(T, State, [Con|Accum])
+ end;
+lookup_constraints(_, _, _) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%% Given a list of Constrain IDs we want to delet the related constraints.
+%% We need also to return the ConstraintInfoSeq described related to the
+%% given ID's.
+delete_constraints([], State) ->
+ State;
+delete_constraints([H|T], State)
+ when is_record(H, 'CosNotifyFilter_MappingConstraintInfo') ->
+ case catch ?del_Constraint(State,
+ H#'CosNotifyFilter_MappingConstraintInfo'.constraint_id) of
+ {ok, NewState} ->
+ delete_constraints(T, NewState);
+ Reason ->
+ orber:dbg("[~p] 'CosNotifyFilter_MappingFilter':modify_mapping_constraints().~n"
+ "Unable to remove: ~p~n"
+ "Reason: ~p~n",
+ [?LINE, H, Reason], ?DEBUG_LEVEL),
+ delete_constraints(T, State)
+ end;
+delete_constraints([H|T], State) ->
+ case catch ?del_Constraint(State,H) of
+ {ok, NewState} ->
+ delete_constraints(T, NewState);
+ Reason ->
+ orber:dbg("[~p] 'CosNotifyFilter_MappingFilter':modify_mapping_constraints().~n"
+ "Unable to remove: ~p~n"
+ "Reason: ~p~n",
+ [?LINE, H, Reason], ?DEBUG_LEVEL),
+ delete_constraints(T, State)
+ end.
+
+%%-----------------------------------------------------------
+%% Function : try_create_filters/2
+%% Arguments: CL - #'CosNotifyFilter_MappingConstraintPair{
+%% constraint_expression =
+%% #'CosNotifyFilter_ConstraintExp'{
+%% event_types =
+%% [#'CosNotification_EventType'{
+%% domain_name = Str, type_name = Str}]
+%% constraint_expr = Str},
+%% result_to_set = Any}
+%% Returns : {State, AccumList}
+%%-----------------------------------------------------------
+%% !!!!!! This function may not alter any data in DB in any way !!!!!!!!!!
+try_create_filters(State, CL) ->
+ try_create_filters(State, CL, [], []).
+try_create_filters(State, [], Accum, InfoSeq) ->
+ {State, Accum, InfoSeq};
+try_create_filters(State, [#'CosNotifyFilter_MappingConstraintPair'
+ {constraint_expression =
+ #'CosNotifyFilter_ConstraintExp'{event_types = Types,
+ constraint_expr = Con},
+ result_to_set=Any}|T], Accum, InfoSeq) ->
+ case catch {?is_EqualType(State,Any), cosNotification_Filter:create_filter(Con)} of
+ {false, _} ->
+ corba:raise(#'CosNotifyFilter_InvalidValue'
+ {constr = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con},
+ value=Any});
+ {_, {ok, Tree}} ->
+ case catch cosNotification_Filter:check_types(Types) of
+ true ->
+ ID = ?new_Id(State),
+ Key = ?not_CreateDBKey,
+ try_create_filters(?set_IdCounter(State, ID), T,
+ [{ID, true, [], Key, Types, Con, Tree, Any}|Accum],
+ [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]);
+ {ok, Which, WC} ->
+ ID = ?new_Id(State),
+ Key = ?not_CreateDBKey,
+ try_create_filters(?set_IdCounter(State, ID), T,
+ [{ID, Which, WC, Key, Types, Con, Tree, Any}|Accum],
+ [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]);
+ _ ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+ _ ->
+ corba:raise(#'CosNotifyFilter_InvalidConstraint'
+ {constr = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con}})
+ end;
+try_create_filters(State, [#'CosNotifyFilter_MappingConstraintInfo'
+ {constraint_expression = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con},
+ constraint_id=ID,
+ value=Any}|T], Accum, InfoSeq) ->
+ case catch cosNotification_Filter:create_filter(Con) of
+ {ok, Tree} ->
+ case catch cosNotification_Filter:check_types(Types) of
+ true ->
+ Key = ?not_CreateDBKey,
+ try_create_filters(State, T,
+ [{ID, true, [], Key, Types, Con, Tree, Any}|Accum],
+ [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]);
+ {ok, Which, WC} ->
+ Key = ?not_CreateDBKey,
+ try_create_filters(State, T,
+ [{ID, Which, WC, Key, Types, Con, Tree, Any}|Accum],
+ [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]);
+ _ ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+ _ ->
+ corba:raise(#'CosNotifyFilter_InvalidConstraint'
+ {constr = #'CosNotifyFilter_ConstraintExp'
+ {event_types = Types, constraint_expr = Con}})
+ end;
+try_create_filters(_,_,_,_) ->
+ %% The list contained something else but ConstraintExp.
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%-----------------------------------------------------------
+%% Function : store_filters/4
+%% Arguments: Filters - a list of filters.
+%% Returns :
+%%-----------------------------------------------------------
+
+store_filters(State, []) ->
+ State;
+store_filters(State, [{ID, Which, WC, Key, Types, Con, Tree, Any}|T]) ->
+ ?add_ParseTree(State, Key, Tree),
+ write_types(State, Types, ID, Key),
+ store_filters(?add_Constraint(State, ID, Con, Which, WC, Key, Types, Any), T).
+
+
+write_types(_State, [],_, _) ->
+ ok;
+write_types(State, [EventType|T], ID, Key) ->
+ ?add_Type(State, ID, EventType, Key),
+ ?debug_print("FILTER: ~p ~p ~p~n", [ID, Key, EventType]),
+ write_types(State, T, ID, Key).
+
+%%-----------------------------------------------------------
+%% Function : match_any_event
+%% Arguments: Event - #any{}
+%% Returns :
+%%-----------------------------------------------------------
+match_any_event(State, _Event, []) ->
+ ?debug_print("FILTER REJECTED: ~p~n", [_Event]),
+ {reply, {false, ?get_DefAny(State)}, State};
+match_any_event(State, Event, [{_, _, _, _, Key, Any}|T]) ->
+ case catch cosNotification_Filter:eval(?get_ParseTree(State,Key), Event) of
+ true ->
+ ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]),
+ {reply, {true, Any}, State};
+ _ ->
+ match_any_event(State, Event, T)
+ end.
+
+
+%%-----------------------------------------------------------
+%% Function : match_str_event
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+
+match_str_event(State, _Event, []) ->
+ ?debug_print("FILTER REJECTED: ~p~n", [_Event]),
+ {reply, {false, ?get_DefAny(State)}, State};
+match_str_event(State, Event, [{ID, _Con, Which, WC, Key, _Types, Any}|T]) ->
+ ET = ((Event#'CosNotification_StructuredEvent'.header)
+ #'CosNotification_EventHeader'.fixed_header)
+ #'CosNotification_FixedEventHeader'.event_type,
+ CheckList =
+ case Which of
+ both ->
+ [ET];
+ domain ->
+ [ET,
+ ET#'CosNotification_EventType'{type_name=""},
+ ET#'CosNotification_EventType'{type_name="*"}];
+ type ->
+ [ET,
+ ET#'CosNotification_EventType'{domain_name=""},
+ ET#'CosNotification_EventType'{domain_name="*"}];
+ _ ->
+ [ET,
+ ET#'CosNotification_EventType'{type_name=""},
+ ET#'CosNotification_EventType'{type_name="*"},
+ ET#'CosNotification_EventType'{domain_name=""},
+ ET#'CosNotification_EventType'{domain_name="*"}]
+ end,
+ case check_DB(State, ID, CheckList) of
+ false ->
+ %% No match, may have used wildcards, e.g., "dom*".
+ case catch cosNotification_Filter:match_types(
+ ET#'CosNotification_EventType'.domain_name,
+ ET#'CosNotification_EventType'.type_name,
+ WC) of
+ true ->
+ case catch cosNotification_Filter:eval(?get_ParseTree(State,Key),
+ Event) of
+ true ->
+ ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]),
+ {reply, {true, Any}, State};
+ _ ->
+ match_str_event(State, Event, T)
+ end;
+ _->
+ match_str_event(State, Event, T)
+ end;
+ Key ->
+ case catch cosNotification_Filter:eval(?get_ParseTree(State,Key),
+ Event) of
+ true ->
+ ?debug_print("FILTER APPROVED: ~p~n", [Event]),
+ {reply, {true, Any}, State};
+ _ ->
+ match_str_event(State, Event, T)
+ end
+ end.
+
+check_DB(_, _, []) ->
+ false;
+check_DB(State, ID, [H|T]) ->
+ case ?match_Type(State, ID, H) of
+ [] ->
+ check_DB(State, ID, T);
+ [{_, K, types}|_] ->
+ K
+ end.
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
+
diff --git a/lib/cosNotification/src/CosTypedEvent.idl b/lib/cosNotification/src/CosTypedEvent.idl
new file mode 100644
index 0000000000..d77c37731a
--- /dev/null
+++ b/lib/cosNotification/src/CosTypedEvent.idl
@@ -0,0 +1,57 @@
+#ifndef _COS_TYPED_EVENT_IDL_
+#define _COS_TYPED_EVENT_IDL_
+
+#pragma prefix "omg.org"
+
+#include<CosEvent.idl>
+
+module CosTypedEventComm {
+
+ interface TypedPushConsumer : CosEventComm::PushConsumer {
+ Object get_typed_consumer();
+ };
+
+ interface TypedPullSupplier : CosEventComm::PullSupplier {
+ Object get_typed_supplier();
+ };
+};
+
+module CosTypedEventChannelAdmin {
+
+ exception InterfaceNotSupported {};
+ exception NoSuchImplementation {};
+ typedef string Key;
+
+
+ interface TypedProxyPushConsumer :
+ CosEventChannelAdmin::ProxyPushConsumer,
+ CosTypedEventComm::TypedPushConsumer { };
+
+ interface TypedProxyPullSupplier :
+ CosEventChannelAdmin::ProxyPullSupplier,
+ CosTypedEventComm::TypedPullSupplier { };
+
+ interface TypedSupplierAdmin :
+ CosEventChannelAdmin::SupplierAdmin {
+ TypedProxyPushConsumer obtain_typed_push_consumer(in Key supported_interface)
+ raises(InterfaceNotSupported);
+ CosEventChannelAdmin::ProxyPullConsumer obtain_typed_pull_consumer (in Key uses_interface)
+ raises(NoSuchImplementation);
+ };
+
+ interface TypedConsumerAdmin :
+ CosEventChannelAdmin::ConsumerAdmin {
+ TypedProxyPullSupplier obtain_typed_pull_supplier(in Key supported_interface)
+ raises (InterfaceNotSupported);
+ CosEventChannelAdmin::ProxyPushSupplier obtain_typed_push_supplier(in Key uses_interface)
+ raises(NoSuchImplementation);
+ };
+
+ interface TypedEventChannel {
+ TypedConsumerAdmin for_consumers();
+ TypedSupplierAdmin for_suppliers();
+ void destroy ();
+ };
+};
+
+#endif /* ifndef _COS_TYPED_EVENT_IDL_ */
diff --git a/lib/cosNotification/src/CosTypedNotification.idl b/lib/cosNotification/src/CosTypedNotification.idl
new file mode 100644
index 0000000000..882cde16e0
--- /dev/null
+++ b/lib/cosNotification/src/CosTypedNotification.idl
@@ -0,0 +1,109 @@
+#ifndef _COS_TYPED_NOTIFICATION_IDL_
+#define _COS_TYPED_NOTIFICATION_IDL_
+
+#pragma prefix "omg.org"
+
+#include<CosNotifyChannelAdmin.idl>
+#include<CosTypedEvent.idl>
+#include<CosNotification.idl>
+
+module CosTypedNotifyComm {
+ interface TypedPushConsumer : CosTypedEventComm::TypedPushConsumer, CosNotifyComm::NotifyPublish { }; // TypedPushConsumer
+
+ interface TypedPullSupplier : CosTypedEventComm::TypedPullSupplier, CosNotifyComm::NotifySubscribe { }; // TypedPullSupplier
+}; // CosTypedNotifyComm
+
+
+module CosTypedNotifyChannelAdmin {
+ // Forward declaration
+ interface TypedEventChannelFactory;
+ typedef string Key;
+ interface TypedProxyPushConsumer : CosNotifyChannelAdmin::ProxyConsumer, CosTypedNotifyComm::TypedPushConsumer {
+ void connect_typed_push_supplier (in CosEventComm::PushSupplier push_supplier)
+ raises (CosEventChannelAdmin::AlreadyConnected);
+ }; // TypedProxyPushConsumer
+
+ interface TypedProxyPullSupplier : CosNotifyChannelAdmin::ProxySupplier, CosTypedNotifyComm::TypedPullSupplier {
+ void connect_typed_pull_consumer (in CosEventComm::PullConsumer pull_consumer)
+ raises (CosEventChannelAdmin::AlreadyConnected);
+ }; // TypedProxyPullSupplier
+
+ interface TypedProxyPullConsumer : CosNotifyChannelAdmin::ProxyConsumer, CosNotifyComm::PullConsumer {
+ void connect_typed_pull_supplier (in CosTypedEventComm::TypedPullSupplier pull_supplier)
+ raises (CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises (CosNotifyChannelAdmin::ConnectionAlreadyInactive, CosNotifyChannelAdmin::NotConnected);
+
+ void resume_connection()
+ raises (CosNotifyChannelAdmin::ConnectionAlreadyActive, CosNotifyChannelAdmin::NotConnected);
+ }; // TypedProxyPullConsumer
+
+ interface TypedProxyPushSupplier : CosNotifyChannelAdmin::ProxySupplier, CosNotifyComm::PushSupplier {
+ void connect_typed_push_consumer (in CosTypedEventComm::TypedPushConsumer push_consumer)
+ raises (CosEventChannelAdmin::AlreadyConnected, CosEventChannelAdmin::TypeError);
+
+ void suspend_connection()
+ raises (CosNotifyChannelAdmin::ConnectionAlreadyInactive, CosNotifyChannelAdmin::NotConnected);
+
+ void resume_connection()
+ raises (CosNotifyChannelAdmin::ConnectionAlreadyActive, CosNotifyChannelAdmin::NotConnected);
+ }; // TypedProxyPushSupplier
+
+ interface TypedConsumerAdmin : CosNotifyChannelAdmin::ConsumerAdmin, CosTypedEventChannelAdmin::TypedConsumerAdmin {
+ TypedProxyPullSupplier obtain_typed_notification_pull_supplier(in Key supported_interface,
+ out CosNotifyChannelAdmin::ProxyID proxy_id)
+ raises( CosTypedEventChannelAdmin::InterfaceNotSupported, CosNotifyChannelAdmin::AdminLimitExceeded );
+
+ TypedProxyPushSupplier obtain_typed_notification_push_supplier(in Key uses_interface,
+ out CosNotifyChannelAdmin::ProxyID proxy_id)
+ raises(CosTypedEventChannelAdmin::NoSuchImplementation, CosNotifyChannelAdmin::AdminLimitExceeded);
+ }; // TypedConsumerAdmin
+
+ interface TypedSupplierAdmin : CosNotifyChannelAdmin::SupplierAdmin, CosTypedEventChannelAdmin::TypedSupplierAdmin {
+ TypedProxyPushConsumer obtain_typed_notification_push_consumer(in Key supported_interface,
+ out CosNotifyChannelAdmin::ProxyID proxy_id)
+ raises( CosTypedEventChannelAdmin::InterfaceNotSupported, CosNotifyChannelAdmin::AdminLimitExceeded);
+ TypedProxyPullConsumer obtain_typed_notification_pull_consumer(in Key uses_interface,
+ out CosNotifyChannelAdmin::ProxyID proxy_id )
+ raises(CosTypedEventChannelAdmin::NoSuchImplementation, CosNotifyChannelAdmin::AdminLimitExceeded);
+ }; // TypedSupplierAdmin
+
+ interface TypedEventChannel : CosNotification::QoSAdmin, CosNotification::AdminPropertiesAdmin,
+ CosTypedEventChannelAdmin::TypedEventChannel {
+ readonly attribute TypedEventChannelFactory MyFactory;
+ readonly attribute TypedConsumerAdmin default_consumer_admin;
+ readonly attribute TypedSupplierAdmin default_supplier_admin;
+ readonly attribute CosNotifyFilter::FilterFactory default_filter_factory;
+
+ TypedConsumerAdmin new_for_typed_notification_consumers(in CosNotifyChannelAdmin::InterFilterGroupOperator op,
+ out CosNotifyChannelAdmin::AdminID id);
+
+ TypedSupplierAdmin new_for_typed_notification_suppliers(in CosNotifyChannelAdmin::InterFilterGroupOperator op,
+ out CosNotifyChannelAdmin::AdminID id);
+
+ TypedConsumerAdmin get_consumeradmin (in CosNotifyChannelAdmin::AdminID id )
+ raises (CosNotifyChannelAdmin::AdminNotFound);
+
+ TypedSupplierAdmin get_supplieradmin (in CosNotifyChannelAdmin::AdminID id)
+ raises (CosNotifyChannelAdmin::AdminNotFound);
+
+ CosNotifyChannelAdmin::AdminIDSeq get_all_consumeradmins();
+
+ CosNotifyChannelAdmin::AdminIDSeq get_all_supplieradmins();
+ }; // TypedEventChannel
+
+ interface TypedEventChannelFactory {
+ TypedEventChannel create_typed_channel (in CosNotification::QoSProperties initial_QoS,
+ in CosNotification::AdminProperties initial_admin,
+ out CosNotifyChannelAdmin::ChannelID id)
+ raises( CosNotification::UnsupportedQoS, CosNotification::UnsupportedAdmin);
+
+ CosNotifyChannelAdmin::ChannelIDSeq get_all_typed_channels();
+
+ TypedEventChannel get_typed_event_channel (in CosNotifyChannelAdmin::ChannelID id)
+ raises (CosNotifyChannelAdmin::ChannelNotFound);
+ }; // TypedEventChannelFactory
+}; // CosTypedNotifyChannelAdmin
+
+#endif /* ifndef _COS_TYPED_NOTIFICATION_IDL_ */
diff --git a/lib/cosNotification/src/Makefile b/lib/cosNotification/src/Makefile
new file mode 100644
index 0000000000..637c633e52
--- /dev/null
+++ b/lib/cosNotification/src/Makefile
@@ -0,0 +1,369 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1999-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+include $(ERL_TOP)/make/target.mk
+
+ifeq ($(TYPE),debug)
+ERL_COMPILE_FLAGS += -Ddebug -W
+endif
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSNOTIFICATION_VSN)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/cosNotification-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES = \
+ CosNotification_Common \
+ CosNotifyChannelAdmin_ConsumerAdmin_impl \
+ CosNotifyChannelAdmin_EventChannelFactory_impl \
+ CosNotifyChannelAdmin_EventChannel_impl \
+ CosNotifyChannelAdmin_SupplierAdmin_impl \
+ CosNotifyFilter_Filter_impl \
+ CosNotifyFilter_MappingFilter_impl \
+ CosNotifyFilter_FilterFactory_impl \
+ PullerConsumer_impl \
+ PullerSupplier_impl \
+ PusherConsumer_impl \
+ PusherSupplier_impl \
+ cosNotificationApp \
+ cosNotification_Scanner \
+ cosNotification_Filter \
+ cosNotification_eventDB
+
+ERL_FILES = $(MODULES:%=%.erl)
+HRL_FILES = \
+ CosNotification_Definitions.hrl
+
+YECC_FILES = cosNotification_Grammar.yrl
+
+GEN_YECC_ERL_FILES = cosNotification_Grammar.erl
+
+GEN_YECC_HRL_FILES =
+
+GEN_NOTIFICATION_ERL_FILES = \
+ oe_CosNotification.erl \
+ CosNotification.erl \
+ CosNotification_AdminPropertiesAdmin.erl \
+ CosNotification_EventHeader.erl \
+ CosNotification_EventType.erl \
+ CosNotification_FixedEventHeader.erl \
+ CosNotification_NamedPropertyRange.erl \
+ CosNotification_Property.erl \
+ CosNotification_PropertyError.erl \
+ CosNotification_PropertyRange.erl \
+ CosNotification_QoSAdmin.erl \
+ CosNotification_StructuredEvent.erl \
+ CosNotification_UnsupportedAdmin.erl \
+ CosNotification_UnsupportedQoS.erl \
+ CosNotification_EventBatch.erl \
+ CosNotification_EventTypeSeq.erl \
+ CosNotification_NamedPropertyRangeSeq.erl \
+ CosNotification_PropertyErrorSeq.erl \
+ CosNotification_PropertySeq.erl
+
+GEN_CHANNELADMIN_ERL_FILES = \
+ oe_CosNotifyChannelAdmin.erl \
+ CosNotifyChannelAdmin_AdminLimit.erl \
+ CosNotifyChannelAdmin_AdminLimitExceeded.erl \
+ CosNotifyChannelAdmin_AdminNotFound.erl \
+ CosNotifyChannelAdmin_ChannelNotFound.erl \
+ CosNotifyChannelAdmin_ConnectionAlreadyActive.erl \
+ CosNotifyChannelAdmin_ConnectionAlreadyInactive.erl \
+ CosNotifyChannelAdmin_ConsumerAdmin.erl \
+ CosNotifyChannelAdmin_EventChannel.erl \
+ CosNotifyChannelAdmin_EventChannelFactory.erl \
+ CosNotifyChannelAdmin_NotConnected.erl \
+ CosNotifyChannelAdmin_ProxyConsumer.erl \
+ CosNotifyChannelAdmin_ProxyNotFound.erl \
+ CosNotifyChannelAdmin_ProxyPullConsumer.erl \
+ CosNotifyChannelAdmin_ProxyPullSupplier.erl \
+ CosNotifyChannelAdmin_ProxyPushConsumer.erl \
+ CosNotifyChannelAdmin_ProxyPushSupplier.erl \
+ CosNotifyChannelAdmin_ProxySupplier.erl \
+ CosNotifyChannelAdmin_SequenceProxyPullConsumer.erl \
+ CosNotifyChannelAdmin_SequenceProxyPullSupplier.erl \
+ CosNotifyChannelAdmin_SequenceProxyPushConsumer.erl \
+ CosNotifyChannelAdmin_SequenceProxyPushSupplier.erl \
+ CosNotifyChannelAdmin_StructuredProxyPullConsumer.erl \
+ CosNotifyChannelAdmin_StructuredProxyPullSupplier.erl \
+ CosNotifyChannelAdmin_StructuredProxyPushConsumer.erl \
+ CosNotifyChannelAdmin_StructuredProxyPushSupplier.erl \
+ CosNotifyChannelAdmin_SupplierAdmin.erl \
+ CosNotifyChannelAdmin_AdminIDSeq.erl \
+ CosNotifyChannelAdmin_ChannelIDSeq.erl \
+ CosNotifyChannelAdmin_ProxyIDSeq.erl
+
+GEN_NOTIFYFILTER_ERL_FILES = \
+ oe_CosNotifyFilter.erl \
+ CosNotifyFilter_CallbackNotFound.erl \
+ CosNotifyFilter_ConstraintExp.erl \
+ CosNotifyFilter_ConstraintInfo.erl \
+ CosNotifyFilter_ConstraintNotFound.erl \
+ CosNotifyFilter_DuplicateConstraintID.erl \
+ CosNotifyFilter_Filter.erl \
+ CosNotifyFilter_FilterAdmin.erl \
+ CosNotifyFilter_FilterFactory.erl \
+ CosNotifyFilter_FilterNotFound.erl \
+ CosNotifyFilter_InvalidConstraint.erl \
+ CosNotifyFilter_InvalidGrammar.erl \
+ CosNotifyFilter_InvalidValue.erl \
+ CosNotifyFilter_MappingConstraintInfo.erl \
+ CosNotifyFilter_MappingConstraintPair.erl \
+ CosNotifyFilter_MappingFilter.erl \
+ CosNotifyFilter_UnsupportedFilterableData.erl \
+ CosNotifyFilter_CallbackIDSeq.erl \
+ CosNotifyFilter_ConstraintExpSeq.erl \
+ CosNotifyFilter_ConstraintIDSeq.erl \
+ CosNotifyFilter_ConstraintInfoSeq.erl \
+ CosNotifyFilter_FilterIDSeq.erl \
+ CosNotifyFilter_MappingConstraintInfoSeq.erl \
+ CosNotifyFilter_MappingConstraintPairSeq.erl
+
+GEN_NOTIFYCOMM_ERL_FILES = \
+ oe_CosNotifyComm.erl \
+ CosNotifyComm_InvalidEventType.erl \
+ CosNotifyComm_NotifyPublish.erl \
+ CosNotifyComm_NotifySubscribe.erl \
+ CosNotifyComm_PullConsumer.erl \
+ CosNotifyComm_PullSupplier.erl \
+ CosNotifyComm_PushConsumer.erl \
+ CosNotifyComm_PushSupplier.erl \
+ CosNotifyComm_SequencePullConsumer.erl \
+ CosNotifyComm_SequencePullSupplier.erl \
+ CosNotifyComm_SequencePushConsumer.erl \
+ CosNotifyComm_SequencePushSupplier.erl \
+ CosNotifyComm_StructuredPullConsumer.erl \
+ CosNotifyComm_StructuredPullSupplier.erl \
+ CosNotifyComm_StructuredPushConsumer.erl \
+ CosNotifyComm_StructuredPushSupplier.erl \
+
+GEN_OE_EVENTCOMM_ERL_FILES = \
+ oe_cosNotificationAppComm.erl \
+ oe_CosNotificationComm_Event.erl
+
+EXTERNAL_INC_PATH = ../include
+
+GEN_NOTIFICATION_HRL_FILES = \
+ oe_CosNotification.hrl \
+ CosNotification.hrl \
+ CosNotification_AdminPropertiesAdmin.hrl \
+ CosNotification_QoSAdmin.hrl \
+
+EXTERNAL_GEN_NOTIFICATION_HRL_FILES = \
+ $(GEN_NOTIFICATION_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%)
+
+GEN_CHANNELADMIN_HRL_FILES = \
+ oe_CosNotifyChannelAdmin.hrl \
+ CosNotifyChannelAdmin.hrl \
+ CosNotifyChannelAdmin_ConsumerAdmin.hrl \
+ CosNotifyChannelAdmin_EventChannel.hrl \
+ CosNotifyChannelAdmin_EventChannelFactory.hrl \
+ CosNotifyChannelAdmin_ProxyConsumer.hrl \
+ CosNotifyChannelAdmin_ProxyPullConsumer.hrl \
+ CosNotifyChannelAdmin_ProxyPullSupplier.hrl \
+ CosNotifyChannelAdmin_ProxyPushConsumer.hrl \
+ CosNotifyChannelAdmin_ProxyPushSupplier.hrl \
+ CosNotifyChannelAdmin_ProxySupplier.hrl \
+ CosNotifyChannelAdmin_SequenceProxyPullConsumer.hrl \
+ CosNotifyChannelAdmin_SequenceProxyPullSupplier.hrl \
+ CosNotifyChannelAdmin_SequenceProxyPushConsumer.hrl \
+ CosNotifyChannelAdmin_SequenceProxyPushSupplier.hrl \
+ CosNotifyChannelAdmin_StructuredProxyPullConsumer.hrl \
+ CosNotifyChannelAdmin_StructuredProxyPullSupplier.hrl \
+ CosNotifyChannelAdmin_StructuredProxyPushConsumer.hrl \
+ CosNotifyChannelAdmin_StructuredProxyPushSupplier.hrl \
+ CosNotifyChannelAdmin_SupplierAdmin.hrl \
+
+EXTERNAL_GEN_CHANNELADMIN_HRL_FILES = \
+ $(GEN_CHANNELADMIN_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%)
+
+GEN_NOTIFYFILTER_HRL_FILES = \
+ oe_CosNotifyFilter.hrl \
+ CosNotifyFilter.hrl \
+ CosNotifyFilter_Filter.hrl \
+ CosNotifyFilter_FilterAdmin.hrl \
+ CosNotifyFilter_FilterFactory.hrl \
+ CosNotifyFilter_MappingFilter.hrl
+
+EXTERNAL_GEN_NOTIFYFILTER_HRL_FILES = \
+ $(GEN_NOTIFYFILTER_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%)
+
+GEN_NOTIFYCOMM_HRL_FILES = \
+ oe_CosNotifyComm.hrl \
+ CosNotifyComm.hrl \
+ CosNotifyComm_NotifyPublish.hrl \
+ CosNotifyComm_NotifySubscribe.hrl \
+ CosNotifyComm_PullConsumer.hrl \
+ CosNotifyComm_PullSupplier.hrl \
+ CosNotifyComm_PushConsumer.hrl \
+ CosNotifyComm_PushSupplier.hrl \
+ CosNotifyComm_SequencePullConsumer.hrl \
+ CosNotifyComm_SequencePullSupplier.hrl \
+ CosNotifyComm_SequencePushConsumer.hrl \
+ CosNotifyComm_SequencePushSupplier.hrl \
+ CosNotifyComm_StructuredPullConsumer.hrl \
+ CosNotifyComm_StructuredPullSupplier.hrl \
+ CosNotifyComm_StructuredPushConsumer.hrl \
+ CosNotifyComm_StructuredPushSupplier.hrl \
+
+EXTERNAL_GEN_NOTIFYCOMM_HRL_FILES = \
+ $(GEN_NOTIFYCOMM_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%)
+
+GEN_OE_EVENTCOMM_HRL_FILES = \
+ oe_cosNotificationAppComm.hrl \
+ oe_CosNotificationComm.hrl \
+ oe_CosNotificationComm_Event.hrl
+
+GEN_ERL_FILES = \
+ $(GEN_NOTIFICATION_ERL_FILES) \
+ $(GEN_OE_EVENTCOMM_ERL_FILES) \
+ $(GEN_NOTIFYCOMM_ERL_FILES) \
+ $(GEN_NOTIFYFILTER_ERL_FILES) \
+ $(GEN_CHANNELADMIN_ERL_FILES) \
+ $(GEN_YECC_ERL_FILES)
+
+GEN_HRL_FILES = \
+ $(EXTERNAL_GEN_NOTIFICATION_HRL_FILES) \
+ $(GEN_OE_EVENTCOMM_HRL_FILES) \
+ $(EXTERNAL_GEN_NOTIFYCOMM_HRL_FILES) \
+ $(EXTERNAL_GEN_NOTIFYFILTER_HRL_FILES) \
+ $(EXTERNAL_GEN_CHANNELADMIN_HRL_FILES) \
+ $(GEN_YECC_HRL_FILES)
+
+
+GEN_FILES = \
+ $(GEN_HRL_FILES) \
+ $(GEN_ERL_FILES)
+
+TARGET_FILES = \
+ $(GEN_ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+IDL_FILES = \
+ CosNotification.idl \
+ CosNotifyChannelAdmin.idl \
+ CosNotifyFilter.idl \
+ CosNotifyComm.idl \
+ cosNotificationAppComm.idl
+
+APPUP_FILE = cosNotification.appup
+APPUP_SRC = $(APPUP_FILE).src
+APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
+
+APP_FILE = cosNotification.app
+APP_SRC = $(APP_FILE).src
+APP_TARGET = $(EBIN)/$(APP_FILE)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosNotification/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin\
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/cosEvent/ebin \
+ -pa $(ERL_TOP)/lib/cosTime/ebin \
+ -I$(ERL_TOP)/lib/cosEvent/src
+
+# The -pa option is just used temporary until erlc can handle
+# includes from other directories than ../include .
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/lib/cosNotification/include \
+ -pa $(ERL_TOP)/lib/cosEvent/include \
+ -pa $(ERL_TOP)/lib/cosTime/include \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosNotification/include \
+ -I$(ERL_TOP)/lib/cosEvent/include \
+ -I$(ERL_TOP)/lib/cosTime/include \
+ +'{parse_transform,sys_pre_attributes}' \
+ +'{attribute,insert,app_vsn,"cosNotification_$(COSNOTIFICATION_VSN)"}'
+
+YECC_COMPILE_FLAGS =
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
+
+debug:
+ @${MAKE} TYPE=debug
+
+cleanb:
+ rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
+ rm -f errs core *~
+
+clean:
+ rm -f $(TARGET_FILES) $(GEN_FILES) $(APP_TARGET) $(APPUP_TARGET)
+ rm -f errs core *~
+
+$(APP_TARGET): $(APP_SRC)
+ sed -e 's;%VSN%;$(VSN);' $< > $@
+
+$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
+ sed -e 's;%VSN%;$(VSN);' $< > $@
+
+docs:
+
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+$(GEN_NOTIFICATION_ERL_FILES) $(EXTERNAL_GEN_NOTIFICATION_HRL_FILES): CosNotification.idl
+ erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotification.cfg"}' CosNotification.idl
+ mv $(GEN_NOTIFICATION_HRL_FILES) $(EXTERNAL_INC_PATH)
+$(GEN_CHANNELADMIN_ERL_FILES) $(EXTERNAL_GEN_CHANNELADMIN_HRL_FILES): CosNotifyChannelAdmin.idl
+ erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyChannelAdmin.cfg"}' CosNotifyChannelAdmin.idl
+ mv $(GEN_CHANNELADMIN_HRL_FILES) $(EXTERNAL_INC_PATH)
+$(GEN_NOTIFYFILTER_ERL_FILES) $(EXTERNAL_GEN_NOTIFYFILTER_HRL_FILES): CosNotifyFilter.idl
+ erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyFilter.cfg"}' CosNotifyFilter.idl
+ mv $(GEN_NOTIFYFILTER_HRL_FILES) $(EXTERNAL_INC_PATH)
+$(GEN_OE_EVENTCOMM_ERL_FILES) $(GEN_OE_EVENTCOMM_HRL_FILES): cosNotificationAppComm.idl
+ erlc $(ERL_IDL_FLAGS) +'{cfgfile,"cosNotificationComm.cfg"}' cosNotificationAppComm.idl
+$(GEN_NOTIFYCOMM_ERL_FILES) $(EXTERNAL_GEN_NOTIFYCOMM_HRL_FILES): CosNotifyComm.idl
+ erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosNotifyComm.cfg"}' CosNotifyComm.idl
+ mv $(GEN_NOTIFYCOMM_HRL_FILES) $(EXTERNAL_INC_PATH)
+$(GEN_YECC_ERL_FILES) $(GEN_YECC_HRL_FILES): cosNotification_Grammar.yrl
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(YECC_FILES) $(RELSYSDIR)/src
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(IDL_FILES) $(YECC_FILES) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/include
+ $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include
+
+release_docs_spec:
diff --git a/lib/cosNotification/src/PullerConsumer_impl.erl b/lib/cosNotification/src/PullerConsumer_impl.erl
new file mode 100644
index 0000000000..fe6f9f8968
--- /dev/null
+++ b/lib/cosNotification/src/PullerConsumer_impl.erl
@@ -0,0 +1,773 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : PullerConsumer_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('PullerConsumer_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+-include_lib("cosEvent/include/CosEventComm.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::ProxyPullConsumer -------------
+-export([connect_any_pull_supplier/4]).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPullConsumer -----
+-export([connect_sequence_pull_supplier/4]).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPullConsumer ---
+-export([connect_structured_pull_supplier/4]).
+
+%%----- CosNotifyChannelAdmin::*ProxyPullConsumer ------------
+-export([suspend_connection/3,
+ resume_connection/3]).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxyConsumer ----
+-export([obtain_subscription_types/4,
+ validate_event_qos/4]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotifyComm::NotifyPublish ------------
+-export([offer_change/5]).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin ------------
+-export([add_filter/4,
+ remove_filter/4,
+ get_filter/4,
+ get_all_filters/3,
+ remove_all_filters/3]).
+
+%%----- Inherit from CosEventComm::PullConsumer -------------
+-export([disconnect_pull_consumer/3]).
+
+%%----- Inherit from CosNotifyComm::SequencePullConsumer ----
+-export([disconnect_sequence_pull_consumer/3]).
+
+%%----- Inherit from CosNotifyComm::StructuredPullConsumer --
+-export([disconnect_structured_pull_consumer/3]).
+
+%%----- Inherit from CosEventChannelAdmin::ProxyPullConsumer
+-export([connect_pull_supplier/4]).
+
+
+%% Attributes (external) CosNotifyChannelAdmin::ProxySupplier
+-export(['_get_MyType'/3,
+ '_get_MyAdmin'/3]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {myType,
+ myAdmin,
+ myAdminPid,
+ myChannel,
+ myFilters = [],
+ myOperator,
+ idCounter = 0,
+ client,
+ qosGlobal,
+ qosLocal,
+ suspended = false,
+ pullTimer,
+ pullInterval,
+ publishType = false,
+ etsR,
+ eventCounter = 0,
+ eventDB,
+ this}).
+
+%% Data structures constructors
+-define(get_InitState(_MyT, _MyA, _MyAP, _QS, _LQS, _Ch, _PI, _MyOP, _GT, _GL, _TR),
+ #state{myType = _MyT,
+ myAdmin = _MyA,
+ myAdminPid = _MyAP,
+ myChannel = _Ch,
+ myOperator = _MyOP,
+ qosGlobal = _QS,
+ qosLocal = _LQS,
+ pullInterval = _PI,
+ etsR = ets:new(oe_ets, [set, protected]),
+ eventDB = cosNotification_eventDB:create_db(_LQS, _GT, _GL, _TR)}).
+
+%%-------------- Data structures selectors -----------------
+%% Attributes
+-define(get_MyType(S), S#state.myType).
+-define(get_MyAdmin(S), S#state.myAdmin).
+-define(get_MyAdminPid(S), S#state.myAdminPid).
+-define(get_MyChannel(S), S#state.myChannel).
+-define(get_MyOperator(S), S#state.myOperator).
+%% Client Object
+-define(get_Client(S), S#state.client).
+%% QoS
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+%% Filters
+-define(get_Filter(S, I), find_obj(lists:keysearch(I, 1, S#state.myFilters))).
+-define(get_AllFilter(S), S#state.myFilters).
+-define(get_AllFilterID(S), find_ids(S#state.myFilters)).
+%% Admin
+-define(get_PullInterval(S), S#state.pullInterval).
+-define(get_PullTimer(S), S#state.pullTimer).
+-define(get_PacingInterval(S), round(?not_GetPacingInterval((S#state.qosLocal))/10000000)).
+-define(get_BatchLimit(S), ?not_GetMaximumBatchSize((S#state.qosLocal))).
+%% Publish
+-define(get_AllPublish(S), lists:flatten(ets:match(S#state.etsR,
+ {'$1',publish}))).
+-define(get_PublishType(S), S#state.publishType).
+%% ID
+-define(get_IdCounter(S), S#state.idCounter).
+%% Event
+-define(get_Event(S), cosNotification_eventDB:get_event(S#state.eventDB)).
+-define(get_Events(S,M), cosNotification_eventDB:get_events(S#state.eventDB, M)).
+-define(get_EventCounter(S), S#state.eventCounter).
+
+%%-------------- Data structures modifiers -----------------
+%% Client Object
+-define(set_Client(S,D), S#state{client=D}).
+-define(del_Client(S), S#state{client=undefined}).
+-define(set_Suspended(S), S#state{client=true}).
+-define(set_NotSuspended(S), S#state{client=false}).
+-define(set_Unconnected(S), S#state{client=undefined}).
+%% QoS
+-define(set_LocalQoS(S,D), S#state{qosLocal=D}).
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+%% Filters
+-define(add_Filter(S,I,O), S#state{myFilters=[{I,O}|S#state.myFilters]}).
+-define(del_Filter(S,I), S#state{myFilters=
+ delete_obj(lists:keydelete(I, 1, S#state.myFilters),
+ S#state.myFilters)}).
+-define(del_AllFilter(S), S#state{myFilters=[]}).
+%% Admin
+-define(set_PullInterval(S,V), S#state{pullInterval=V}).
+-define(set_PullTimer(S,T), S#state{pullTimer=T}).
+%% Publish
+-define(add_Publish(S,E), ets:insert(S#state.etsR, {E, publish})).
+-define(del_Publish(S,E), ets:delete(S#state.etsR, E)).
+-define(set_PublishType(S,T), S#state{publishType=T}).
+%% ID
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+%% Event
+-define(add_Event(S,E), cosNotification_eventDB:add_event(S#state.eventDB, E)).
+-define(update_EventDB(S,Q), S#state{eventDB=
+ cosNotification_eventDB:update(S#state.eventDB, Q)}).
+
+-define(set_EventCounter(S,V), S#state{eventCounter=V}).
+-define(add_to_EventCounter(S,V),S#state{eventCounter=S#state.eventCounter+V}).
+-define(reset_EventCounter(S), S#state{eventCounter=0}).
+-define(increase_EventCounter(S),S#state{eventCounter=(S#state.eventCounter+1)}).
+-define(decrease_EventCounter(S),S#state{eventCounter=S#state.eventCounter-1}).
+-define(add_ToEventCounter(S,A), S#state{eventCounter=(S#state.eventCounter+A)}).
+-define(sub_FromEventCounter(S,_A), S#state{eventCounter=(S#state.eventCounter-_A)}).
+-define(set_EventCounterTo(S,V), S#state{eventCounter=V}).
+
+%%-------------- MISC ----------------------------------------
+-define(is_ANY(S), S#state.myType == 'PULL_ANY').
+-define(is_STRUCTURED(S), S#state.myType == 'PULL_STRUCTURED').
+-define(is_SEQUENCE(S), S#state.myType == 'PULL_SEQUENCE').
+-define(is_ANDOP(S), S#state.myOperator == 'AND_OP').
+-define(is_UnConnected(S), S#state.client == undefined).
+-define(is_Connected(S), S#state.client =/= undefined).
+-define(is_Suspended(S), S#state.suspended == true).
+-define(is_NotSuspended(S), S#state.suspended == false).
+-define(is_PersistentConnection(S),
+ ?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_PersistentEvent(S),
+ ?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent).
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?DBG("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, Reason} when ?get_MyAdminPid(State) == Pid->
+ ?DBG("PARENT ADMIN: ~p TERMINATED.~n",[Reason]),
+ {stop, Reason, State};
+ {'EXIT', _Pid, _Reason} ->
+ ?DBG("PROXYPUSHSUPPLIER: ~p TERMINATED.~n",[_Reason]),
+ {noreply, State};
+ pull ->
+ try_pull_events(State);
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyType, MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel, Options, Operator]) ->
+ process_flag(trap_exit, true),
+ Secs = timer:seconds('CosNotification_Common':get_option(pullInterval,
+ Options,
+ ?not_DEFAULT_SETTINGS)),
+ GCTime = 'CosNotification_Common':get_option(gcTime, Options,
+ ?not_DEFAULT_SETTINGS),
+ GCLimit = 'CosNotification_Common':get_option(gcLimit, Options,
+ ?not_DEFAULT_SETTINGS),
+ TimeRef = 'CosNotification_Common':get_option(timeService, Options,
+ ?not_DEFAULT_SETTINGS),
+ timer:start(),
+ {ok, ?get_InitState(MyType, MyAdmin, MyAdminPid, InitQoS,
+ LQS, MyChannel, Secs, Operator, GCTime,
+ GCLimit, TimeRef)}.
+
+terminate(_Reason, State) when ?is_UnConnected(State) ->
+ %% We are currently not connected to a client. Hence, no need for sending
+ %% a disconnect request.
+ stop_timer(State),
+ ok;
+terminate(_Reason, State) when ?is_ANY(State) ->
+ stop_timer(State),
+ 'CosNotification_Common':disconnect('CosEventComm_PullSupplier',
+ disconnect_pull_supplier,
+ ?get_Client(State));
+terminate(_Reason, State) when ?is_SEQUENCE(State) ->
+ stop_timer(State),
+ 'CosNotification_Common':disconnect('CosNotifyComm_SequencePullSupplier',
+ disconnect_sequence_pull_supplier,
+ ?get_Client(State));
+terminate(_Reason, State) when ?is_STRUCTURED(State) ->
+ stop_timer(State),
+ 'CosNotification_Common':disconnect('CosNotifyComm_StructuredPullSupplier',
+ disconnect_structured_pull_supplier,
+ ?get_Client(State)).
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_ProxyConsumer attributes ------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyType'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyType'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyType(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyAdmin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyAdmin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyAdmin(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----- CosEventChannelAdmin::ProxyPullConsumer -------------
+%%----------------------------------------------------------%
+%% function : connect_pull_supplier
+%% Arguments: Client - CosEventComm::PullSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%% Both exceptions from CosEventChannelAdmin!!!
+%%-----------------------------------------------------------
+connect_pull_supplier(OE_THIS, OE_FROM, State, Client) ->
+ connect_any_pull_supplier(OE_THIS, OE_FROM, State, Client).
+
+%%----- CosNotifyChannelAdmin::ProxyPullConsumer ------------
+%%----------------------------------------------------------%
+%% function : connect_any_pull_supplier
+%% Arguments: Client - CosEventComm::PullSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%% Both exceptions from CosEventChannelAdmin!!!
+%%-----------------------------------------------------------
+connect_any_pull_supplier(OE_THIS, _OE_FROM, State, Client) when ?is_ANY(State) ->
+ 'CosNotification_Common':type_check(Client, 'CosEventComm_PullSupplier'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ NewState = start_timer(State),
+ {reply, ok, NewState#state{client = Client, this = OE_THIS}}
+ end;
+connect_any_pull_supplier(_, _, _,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPullConsumer ----
+%%----------------------------------------------------------%
+%% function : connect_sequence_pull_supplier
+%% Arguments: Client - CosNotifyComm::SequencePullSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%%-----------------------------------------------------------
+connect_sequence_pull_supplier(OE_THIS, _OE_FROM, State, Client) when ?is_SEQUENCE(State) ->
+ 'CosNotification_Common':type_check(Client, 'CosNotifyComm_SequencePullSupplier'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ NewState = start_timer(State),
+ {reply, ok, NewState#state{client = Client, this = OE_THIS}}
+ end;
+connect_sequence_pull_supplier(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPullConsumer --
+%%----------------------------------------------------------%
+%% function : connect_structured_pull_supplier
+%% Arguments: Client - CosNotifyComm::StructuredPullSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%%-----------------------------------------------------------
+connect_structured_pull_supplier(OE_THIS, _OE_FROM, State, Client) when ?is_STRUCTURED(State) ->
+ 'CosNotification_Common':type_check(Client, 'CosNotifyComm_StructuredPullSupplier'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ NewState = start_timer(State),
+ {reply, ok, NewState#state{client = Client, this = OE_THIS}}
+ end;
+connect_structured_pull_supplier(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::*ProxyPullConsumer -----------
+%%----------------------------------------------------------%
+%% function : suspend_connection
+%% Arguments:
+%% Returns : ok | {'EXCEPTION', #'ConnectionAlreadyInactive'{}} |
+%% {'EXCEPTION', #'NotConneced'{}}
+%%-----------------------------------------------------------
+suspend_connection(_OE_THIS, _OE_FROM, State) when ?is_Connected(State) ->
+ if
+ ?is_Suspended(State) ->
+ corba:raise(#'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{});
+ true ->
+ stop_timer(State),
+ {reply, ok, ?set_Suspended(State)}
+ end;
+suspend_connection(_, _, _) ->
+ corba:raise(#'CosNotifyChannelAdmin_NotConnected'{}).
+
+%%----------------------------------------------------------%
+%% function : resume_connection
+%% Arguments:
+%% Returns : ok | {'EXCEPTION', #'ConnectionAlreadyActive'{}} |
+%% {'EXCEPTION', #'NotConneced'{}}
+%%-----------------------------------------------------------
+resume_connection(_OE_THIS, _OE_FROM, State) when ?is_Connected(State) ->
+ if
+ ?is_NotSuspended(State) ->
+ corba:raise(#'CosNotifyChannelAdmin_ConnectionAlreadyActive'{});
+ true ->
+ NewState = start_timer(State),
+ {reply, ok, ?set_NotSuspended(NewState)}
+ end;
+resume_connection(_, _, _) ->
+ corba:raise(#'CosNotifyChannelAdmin_NotConnected'{}).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxyConsumer ---
+%%----------------------------------------------------------%
+%% function : obtain_subscription_types
+%% Arguments: Mode - enum 'ObtainInfoMode' (CosNotifyChannelAdmin)
+%% Returns : CosNotification::EventTypeSeq
+%%-----------------------------------------------------------
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_OFF') ->
+ {reply, ?get_AllPublish(State), ?set_PublishType(State, false)};
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_ON') ->
+ {reply, ?get_AllPublish(State), ?set_PublishType(State, true)};
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_OFF') ->
+ {reply, [], ?set_PublishType(State, false)};
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_ON') ->
+ {reply, [], ?set_PublishType(State, true)};
+obtain_subscription_types(_,_,_,What) ->
+ orber:dbg("[~p] PullerConsumer:obtain_subscription_types(~p);~n"
+ "Incorrect enumerant", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : validate_event_qos
+%% Arguments: RequiredQoS - CosNotification::QoSProperties
+%% Returns : ok | {'EXCEPTION', #'UnsupportedQoS'{}}
+%% AvilableQoS - CosNotification::NamedPropertyRangeSeq (out)
+%%-----------------------------------------------------------
+validate_event_qos(_OE_THIS, _OE_FROM, State, RequiredQoS) ->
+ AvilableQoS = 'CosNotification_Common':validate_event_qos(RequiredQoS,
+ ?get_LocalQoS(State)),
+ {reply, {ok, AvilableQoS}, State}.
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {NewQoS, LQS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ NewState = ?update_EventDB(State, LQS),
+ {reply, ok, ?set_BothQoS(NewState, NewQoS, LQS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS}
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotifyComm::NotifyPublish -----------
+%%----------------------------------------------------------%
+%% function : offer_change
+%% Arguments: Added - #'CosNotification_EventType'{}
+%% Removed - #'CosNotification_EventType'{}
+%% Returns : ok |
+%% {'EXCEPTION', #'CosNotifyComm_InvalidEventType'{}}
+%%-----------------------------------------------------------
+offer_change(_OE_THIS, _OE_FROM, State, Added, Removed) ->
+ cosNotification_Filter:validate_types(Added),
+ cosNotification_Filter:validate_types(Removed),
+ %% On this "side" we don't really care about which
+ %% type of events the client will supply.
+ %% Perhaps, later on, if we want to check this against Filters
+ %% associated with this object we may change this approach, i.e., if
+ %% the filter will not allow passing certain event types. But the
+ %% user should see to that that situation never occurs. It would add
+ %% extra overhead. Also see PusherSupplier- and PullerSuppler-
+ %% 'subscription_change'.
+ update_publish(add, State, Added),
+ update_publish(remove, State, Removed),
+ case ?get_PublishType(State) of
+ true ->
+ %% Perhaps we should handle exception here?!
+ %% Probably not. Better to stay "on-line".
+ catch 'CosNotifyComm_NotifySubscribe':
+ subscription_change(?get_Client(State), Added, Removed),
+ ok;
+ _->
+ ok
+ end,
+ {reply, ok, State}.
+
+update_publish(_, _, [])->
+ ok;
+update_publish(add, State, [H|T]) ->
+ ?add_Publish(State, H),
+ update_publish(add, State, T);
+update_publish(remove, State, [H|T]) ->
+ ?del_Publish(State, H),
+ update_publish(remove, State, T).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin -----------
+%%----------------------------------------------------------%
+%% function : add_filter
+%% Arguments: Filter - CosNotifyFilter::Filter
+%% Returns : FilterID - long
+%%-----------------------------------------------------------
+add_filter(_OE_THIS, _OE_FROM, State, Filter) ->
+ 'CosNotification_Common':type_check(Filter, 'CosNotifyFilter_Filter'),
+ FilterID = ?new_Id(State),
+ NewState = ?set_IdCounter(State, FilterID),
+ {reply, FilterID, ?add_Filter(NewState, FilterID, Filter)}.
+
+%%----------------------------------------------------------%
+%% function : remove_filter
+%% Arguments: FilterID - long
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ok, ?del_Filter(State, FilterID)};
+remove_filter(_,_,_,What) ->
+ orber:dbg("[~p] PullerConsumer:remove_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_filter
+%% Arguments: FilterID - long
+%% Returns : Filter - CosNotifyFilter::Filter |
+%% {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}
+%%-----------------------------------------------------------
+get_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ?get_Filter(State, FilterID), State};
+get_filter(_,_,_,What) ->
+ orber:dbg("[~p] PullerConsumer:get_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_filters
+%% Arguments: -
+%% Returns : Filter - CosNotifyFilter::FilterIDSeq
+%%-----------------------------------------------------------
+get_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_AllFilterID(State), State}.
+
+%%----------------------------------------------------------%
+%% function : remove_all_filters
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ok, ?del_AllFilter(State)}.
+
+%%----- Inherit from CosEventComm::PullConsumer -------------
+%%----------------------------------------------------------%
+%% function : disconnect_pull_consumer
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_pull_consumer(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----- Inherit from CosNotifyComm::SequencePullConsumer ----
+%%----------------------------------------------------------%
+%% function : disconnect_sequence_pull_consumer
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_sequence_pull_consumer(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----- Inherit from CosNotifyComm::StructuredPullConsumer ----
+%%----------------------------------------------------------%
+%% function : disconnect_structured_pull_consumer
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_structured_pull_consumer(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj({value, {_, Obj}}) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}.
+
+find_ids(List) -> find_ids(List, []).
+find_ids([], Acc) -> Acc;
+find_ids([{I,_}|T], Acc) -> find_ids(T, [I|Acc]);
+find_ids(What, _) ->
+ orber:dbg("[~p] PullerConsumer:find_ids();~n"
+ "Id corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%% Delete a single object.
+%% The list don not differ, i.e., no filter removed, raise exception.
+delete_obj(List,List) -> corba:raise(#'CosNotifyFilter_FilterNotFound'{});
+delete_obj(List,_) -> List.
+
+%% Start timer which send a message each time we should pull for new events.
+start_timer(State) ->
+ case catch timer:send_interval(?get_PullInterval(State), pull) of
+ {ok,PullTRef} ->
+ ?DBG("PULL CONSUMER STARTED PULL TIMER ~p~n",
+ [?get_PullInterval(State)]),
+ ?set_PullTimer(State, PullTRef);
+ What ->
+ orber:dbg("[~p] PullerConsumer:start_timer();~n"
+ "Unable to invoke timer:send_interval/2: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+stop_timer(State) ->
+ ?DBG("PULL CONSUMER STOPPED TIMER~n",[]),
+ timer:cancel(?get_PullTimer(State)).
+
+%% Try pull event(s); which method is determined by which type this proxy is.
+try_pull_events(State) when ?is_ANY(State) ->
+ case catch 'CosEventComm_PullSupplier':try_pull(?get_Client(State)) of
+ {_,false} ->
+ {noreply, State};
+ {Event, true} ->
+ case ?not_isConvertedStructured(Event) of
+ true ->
+ forward(seq, State,
+ cosNotification_eventDB:filter_events([any:get_value(Event)],
+ ?get_AllFilter(State)));
+ _ ->
+ forward(any, State,
+ cosNotification_eventDB:filter_events([Event],
+ ?get_AllFilter(State)))
+ end;
+ _->
+ {noreply, State}
+ end;
+try_pull_events(State) when ?is_SEQUENCE(State) ->
+ case catch 'CosNotifyComm_SequencePullSupplier':
+ try_pull_structured_events(?get_Client(State), ?get_BatchLimit(State)) of
+ {_,false} ->
+ {noreply, State};
+ {EventSeq, true} ->
+ %% We cannot convert parts of the sequence to any, event though they
+ %% are converted from any to structured. Would be 'impossible' to send.
+ forward(seq, State,
+ cosNotification_eventDB:filter_events(EventSeq,
+ ?get_AllFilter(State)));
+ _->
+ {noreply, State}
+ end;
+try_pull_events(State) when ?is_STRUCTURED(State) ->
+ case catch 'CosNotifyComm_StructuredPullSupplier':
+ try_pull_structured_event(?get_Client(State)) of
+ {_,false} ->
+ {noreply, State};
+ {Event, true} when ?not_isConvertedAny(Event) ->
+ forward(any, State,
+ cosNotification_eventDB:filter_events([Event#'CosNotification_StructuredEvent'.remainder_of_body],
+ ?get_AllFilter(State)));
+ {Event, true} ->
+ forward(seq, State,
+ cosNotification_eventDB:filter_events([Event],
+ ?get_AllFilter(State)));
+ _->
+ {noreply, State}
+ end.
+
+
+
+%% Forward events
+forward(_, State, {[], _}) when ?is_ANDOP(State) ->
+ %% Did not pass filtering. Since AND no need to pass on.
+ {noreply, State};
+forward(Type, State, {[], Failed}) ->
+ %% Did not pass filtering, but since OR it may pass Admin filters, hence, pass
+ %% on to Admin
+ forward(Type, State, Failed, ?get_MyAdmin(State), 'MATCH');
+forward(Type, State, {Passed, _}) when ?is_ANDOP(State) ->
+ %% Did pass filtering, but since AND we must pass it to Admin to check against
+ %% its Filters. Just ignore the ones that failed.
+ forward(Type, State, Passed, ?get_MyAdmin(State), 'MATCH');
+forward(Type, State, {Passed, []}) ->
+ %% Did pass filtering, and since OR we can pass it to the Channel directly.
+ forward(Type, State, Passed, ?get_MyChannel(State), 'MATCHED');
+forward(Type, State, {Passed, Failed}) ->
+ %% Some passed filtering, and since OR we can pass the ones that passed directly
+ %% to the channel and the other ones via the admin.
+ forward(Type, State, Passed, ?get_MyChannel(State), 'MATCHED'),
+ forward(Type, State, Failed, ?get_MyAdmin(State), 'MATCH').
+
+forward(any, State, [Event], SendTo, Status) ->
+ case catch oe_CosNotificationComm_Event:callAny(SendTo, Event, Status) of
+ ok ->
+ ?DBG("PROXY FORWARD ANY: ~p~n",[Event]),
+ {noreply, State};
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ orber:dbg("[~p] PullerConsumer:forward();~n"
+ "Admin/Channel no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PullerConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Dropping: ~p", [?LINE, R, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ R ->
+ orber:dbg("[~p] PullerConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, R, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, R}]),
+ {stop, normal, State}
+ end;
+forward(seq, State, Event, SendTo, Status) ->
+ case catch oe_CosNotificationComm_Event:callSeq(SendTo, Event, Status) of
+ ok ->
+ ?DBG("PROXY FORWARD SEQUENCE: ~p~n",[Event]),
+ {noreply, State};
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ orber:dbg("[~p] PullerConsumer:forward();~n"
+ "Admin/Channel no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PullerConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Dropping: ~p", [?LINE, R, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ R ->
+ orber:dbg("[~p] PullerConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, R, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, R}]),
+ {stop, normal, State}
+ end.
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/PullerSupplier_impl.erl b/lib/cosNotification/src/PullerSupplier_impl.erl
new file mode 100644
index 0000000000..9f12f9c742
--- /dev/null
+++ b/lib/cosNotification/src/PullerSupplier_impl.erl
@@ -0,0 +1,914 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : PullerSupplier_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('PullerSupplier_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::ProxyPullSupplier -------------
+-export([connect_any_pull_consumer/4]).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPullSupplier -----
+-export([connect_sequence_pull_consumer/4]).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPullSupplier ---
+-export([connect_structured_pull_consumer/4]).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxySupplier ----
+-export([obtain_offered_types/4,
+ validate_event_qos/4]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotifyComm::NotifySubscribe ----------
+-export([subscription_change/5]).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin ------------
+-export([add_filter/4,
+ remove_filter/4,
+ get_filter/4,
+ get_all_filters/3,
+ remove_all_filters/3]).
+
+%%----- Inherit from CosEventComm::PullSupplier -------------
+-export([pull/3,
+ try_pull/3,
+ disconnect_pull_supplier/3]).
+
+%%----- Inherit from CosNotifyComm::SequencePullSupplier --
+-export([pull_structured_events/4,
+ try_pull_structured_events/4,
+ disconnect_sequence_pull_supplier/3]).
+
+%%----- Inherit from CosNotifyComm::StructuredPullSupplier --
+-export([pull_structured_event/3,
+ try_pull_structured_event/3,
+ disconnect_structured_pull_supplier/3]).
+
+%%----- Inherit from CosEventChannelAdmin::ProxyPullSupplier
+-export([connect_pull_consumer/4]).
+
+%% Attributes (external) CosNotifyChannelAdmin::ProxySupplier
+-export(['_get_MyType'/3,
+ '_get_MyAdmin'/3,
+ '_get_priority_filter'/3,
+ '_set_priority_filter'/4,
+ '_get_lifetime_filter'/3,
+ '_set_lifetime_filter'/4]).
+
+%%--------------- Internal -----------------------------------
+%%----- Inherit from cosNotificationComm --------------------
+-export([callAny/5,
+ callSeq/5]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {myType,
+ myAdmin,
+ myAdminPid,
+ myChannel,
+ myFilters = [],
+ myOperator,
+ idCounter = 0,
+ prioFil,
+ lifetFil,
+ client,
+ qosGlobal,
+ qosLocal,
+ pacingTimer,
+ respondTo,
+ subscribeType = false,
+ subscribeData = true,
+ etsR,
+ eventDB}).
+
+%% Data structures constructors
+-define(get_InitState(_MyT, _MyA, _MyAP, _QS, _LQS, _Ch, _MyOp, _GT, _GL, _TR),
+ #state{myType = _MyT,
+ myAdmin = _MyA,
+ myAdminPid= _MyAP,
+ myChannel = _Ch,
+ myOperator= _MyOp,
+ qosGlobal = _QS,
+ qosLocal = _LQS,
+ etsR = ets:new(oe_ets, [set, protected]),
+ eventDB = cosNotification_eventDB:create_db(_LQS, _GT, _GL, _TR)}).
+
+
+%% Data structures selectors
+%% Attributes
+-define(get_MyType(S), S#state.myType).
+-define(get_MyAdmin(S), S#state.myAdmin).
+-define(get_MyAdminPid(S), S#state.myAdmin).
+-define(get_MyChannel(S), S#state.myChannel).
+-define(get_MyOperator(S), S#state.myOperator).
+-define(get_PrioFil(S), S#state.prioFil).
+-define(get_LifeTFil(S), S#state.lifetFil).
+%% Client Object
+-define(get_Client(S), S#state.client).
+%% QoS
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+%% Filters
+-define(get_Filter(S, I), find_obj(lists:keysearch(I, 1, S#state.myFilters))).
+-define(get_AllFilter(S), S#state.myFilters).
+-define(get_AllFilterID(S), find_ids(S#state.myFilters)).
+%% Event
+-define(get_Event(S), cosNotification_eventDB:get_event(S#state.eventDB)).
+-define(get_Events(S,M), cosNotification_eventDB:get_events(S#state.eventDB, M)).
+-define(get_RespondTo(S), S#state.respondTo).
+%% Amin
+-define(get_PacingTimer(S), S#state.pacingTimer).
+-define(get_PacingInterval(S), round(?not_GetPacingInterval((S#state.qosLocal))/10000000)).
+-define(get_BatchLimit(S), ?not_GetMaximumBatchSize((S#state.qosLocal))).
+%% Subscribe
+-define(get_AllSubscribe(S), lists:flatten(ets:match(S#state.etsR,
+ {'$1',subscribe}))).
+-define(get_SubscribeType(S), S#state.subscribeType).
+-define(get_SubscribeData(S), S#state.subscribeData).
+%% ID
+-define(get_IdCounter(S), S#state.idCounter).
+-define(get_SubscribeDB(S), S#state.etsR).
+
+%% Data structures modifiers
+%% Attributes
+-define(set_PrioFil(S,D), S#state{prioFil=D}).
+-define(set_LifeTFil(S,D), S#state{lifetFil=D}).
+%% Client Object
+-define(set_Client(S,D), S#state{client=D}).
+-define(del_Client(S), S#state{client=undefined}).
+%% QoS
+-define(set_LocalQoS(S,D), S#state{qosLocal=D}).
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+-define(update_EventDB(S,Q), S#state{eventDB=
+ cosNotification_eventDB:update(S#state.eventDB, Q)}).
+%% Filters
+-define(add_Filter(S,I,O), S#state{myFilters=[{I,O}|S#state.myFilters]}).
+-define(del_Filter(S,I), S#state{myFilters=
+ delete_obj(lists:keydelete(I, 1, S#state.myFilters),
+ S#state.myFilters)}).
+-define(del_AllFilter(S), S#state{myFilters=[]}).
+-define(set_Unconnected(S), S#state{client=undefined}).
+-define(reset_RespondTo(S), S#state{respondTo=undefined}).
+-define(set_RespondTo(S,F), S#state{respondTo=F}).
+%% Event
+-define(add_Event(S,E), catch cosNotification_eventDB:
+ add_event(S#state.eventDB, E, S#state.lifetFil, S#state.prioFil)).
+-define(addAndGet_Event(S,E), catch cosNotification_eventDB:
+ add_and_get_event(S#state.eventDB, E, S#state.lifetFil, S#state.prioFil)).
+%% Admin
+-define(set_PacingTimer(S,T), S#state{pacingTimer=T}).
+%% Subscribe
+-define(add_Subscribe(S,E), ets:insert(S#state.etsR, {E, subscribe})).
+-define(del_Subscribe(S,E), ets:delete(S#state.etsR, E)).
+-define(set_SubscribeType(S,T), S#state{subscribeType=T}).
+-define(set_SubscribeData(S,D), S#state{subscribeData=D}).
+%% ID
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+
+%% MISC
+-define(is_ANY(S), S#state.myType == 'PULL_ANY').
+-define(is_STRUCTURED(S), S#state.myType == 'PULL_STRUCTURED').
+-define(is_SEQUENCE(S), S#state.myType == 'PULL_SEQUENCE').
+-define(is_ANDOP(S), S#state.myOperator == 'AND_OP').
+-define(is_UnConnected(S), S#state.client == undefined).
+-define(is_Connected(S), S#state.client =/= undefined).
+-define(is_Waiting(S), S#state.respondTo =/= undefined).
+-define(is_SubscribedFor(S,K), ets:lookup(S#state.etsR, K) =/= []).
+-define(is_BatchLimitReached(S,M), cosNotification_eventDB:
+ status(S#state.eventDB, {batchLimit,
+ ?not_GetMaximumBatchSize((S#state.qosLocal)), M})).
+
+%%----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%-----------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?DBG("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, Reason} when ?get_MyAdminPid(State)==Pid->
+ ?DBG("PARENT ADMIN: ~p TERMINATED.~n",[Reason]),
+ {stop, Reason, State};
+ {'EXIT', _Pid, _Reason} ->
+ ?DBG("PROXYPUSHSUPPLIER: ~p TERMINATED.~n",[_Reason]),
+ {noreply, State};
+ {pacing, TS} when ?is_Waiting(State) ->
+ case ?get_PacingTimer(State) of
+ {_, TS} ->
+ ?DBG("PULL SUPPLIER PACING LIMIT REACHED~n",[]),
+ {RespondTo, Max} = ?get_RespondTo(State),
+ {EventSeq, _} = ?get_Events(State, Max),
+ corba:reply(RespondTo, EventSeq),
+ {noreply, ?reset_RespondTo(State)};
+ _ ->
+ %% Must have been an old timer event, i.e., we reached the
+ %% Batch Limit before Pace limit and we were not able
+ %% to stop the timer before it triggered an event.
+ ?DBG("PULL SUPPLIER OLD PACING LIMIT REACHED~n",[]),
+ {noreply, State}
+ end;
+ {pacing, _} ->
+ ?DBG("PULL SUPPLIER PACING LIMIT REACHED BUT NO CLIENT; IMPOSSIBLE!!!~n",[]),
+ {noreply, State};
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyType, MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel, Options, Operator]) ->
+ process_flag(trap_exit, true),
+ GCTime = 'CosNotification_Common':get_option(gcTime, Options,
+ ?not_DEFAULT_SETTINGS),
+ GCLimit = 'CosNotification_Common':get_option(gcLimit, Options,
+ ?not_DEFAULT_SETTINGS),
+ TimeRef = 'CosNotification_Common':get_option(timeService, Options,
+ ?not_DEFAULT_SETTINGS),
+ {ok, ?get_InitState(MyType, MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel,
+ Operator, GCTime, GCLimit, TimeRef)}.
+
+terminate(_Reason, State) when ?is_UnConnected(State) ->
+ ok;
+terminate(_Reason, State) ->
+ Client = ?get_Client(State),
+ case catch corba_object:is_nil(Client) of
+ false when ?is_ANY(State) ->
+ 'CosNotification_Common':disconnect('CosEventComm_PullConsumer',
+ disconnect_pull_consumer,
+ Client);
+ false when ?is_SEQUENCE(State) ->
+ 'CosNotification_Common':disconnect('CosNotifyComm_SequencePullConsumer',
+ disconnect_sequence_pull_consumer,
+ Client);
+ false when ?is_STRUCTURED(State) ->
+ 'CosNotification_Common':disconnect('CosNotifyComm_StructuredPullConsumer',
+ disconnect_structured_pull_consumer,
+ Client);
+ _ ->
+ ok
+ end.
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_ProxySupplier attributes ------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyType'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyType'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyType(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyAdmin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyAdmin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyAdmin(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_*et_priority_filter'
+%% Type : read/write
+%% Returns :
+%%-----------------------------------------------------------
+'_get_priority_filter'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PrioFil(State), State}.
+'_set_priority_filter'(_OE_THIS, _OE_FROM, State, PrioF) ->
+ {reply, ok, ?set_PrioFil(State, PrioF)}.
+
+
+%%----------------------------------------------------------%
+%% Attribute: '_*et_lifetime_filter'
+%% Type : read/write
+%% Returns :
+%%-----------------------------------------------------------
+'_get_lifetime_filter'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_LifeTFil(State), State}.
+'_set_lifetime_filter'(_OE_THIS, _OE_FROM, State, LifeTF) ->
+ {reply, ok, ?set_LifeTFil(State, LifeTF)}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----- CosEventChannelAdmin::ProxyPullSupplier -------------
+%%----------------------------------------------------------%
+%% function : connect_pull_consumer
+%% Arguments: Client - CosEventComm::PullConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%% Both exceptions from CosEventChannelAdmin!!!
+%%-----------------------------------------------------------
+connect_pull_consumer(OE_THIS, OE_FROM, State, Client) ->
+ connect_any_pull_consumer(OE_THIS, OE_FROM, State, Client).
+
+%%----- CosNotifyChannelAdmin::ProxyPullSupplier ------------
+%%----------------------------------------------------------%
+%% function : connect_any_pull_consumer
+%% Arguments: Client - CosEventComm::PullConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%% Both exceptions from CosEventChannelAdmin!!!
+%%-----------------------------------------------------------
+connect_any_pull_consumer(_OE_THIS, _OE_FROM, State, Client) when ?is_ANY(State) ->
+ ?not_TypeCheck(Client, 'CosEventComm_PullConsumer'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, ?set_Client(State, Client)}
+ end;
+connect_any_pull_consumer(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPullSupplier ----
+%%----------------------------------------------------------%
+%% function : connect_sequence_pull_consumer
+%% Arguments: Client - CosNotifyComm::SequencePullConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%%-----------------------------------------------------------
+connect_sequence_pull_consumer(_OE_THIS, _OE_FROM, State, Client) when ?is_SEQUENCE(State) ->
+ ?not_TypeCheck(Client, 'CosNotifyComm_SequencePullConsumer'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, ?set_Client(State, Client)}
+ end;
+connect_sequence_pull_consumer(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPullSupplier --
+%%----------------------------------------------------------%
+%% function : connect_structured_pull_consumer
+%% Arguments: Client - CosNotifyComm::StructuredPullConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}} |
+%% {'EXCEPTION', #'BAD_OPERATION'{}}
+%%-----------------------------------------------------------
+connect_structured_pull_consumer(_OE_THIS, _OE_FROM, State, Client) when ?is_STRUCTURED(State) ->
+ ?not_TypeCheck(Client, 'CosNotifyComm_StructuredPullConsumer'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, ?set_Client(State, Client)}
+ end;
+connect_structured_pull_consumer(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxySupplier ---
+%%----------------------------------------------------------%
+%% function : obtain_offered_types
+%% Arguments: Mode - enum 'ObtainInfoMode' (CosNotifyChannelAdmin)
+%% Returns : CosNotification::EventTypeSeq
+%%-----------------------------------------------------------
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_OFF') ->
+ {reply, ?get_AllSubscribe(State), ?set_SubscribeType(State, false)};
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_ON') ->
+ {reply, ?get_AllSubscribe(State), ?set_SubscribeType(State, true)};
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_OFF') ->
+ {reply, [], ?set_SubscribeType(State, false)};
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_ON') ->
+ {reply, [], ?set_SubscribeType(State, true)};
+obtain_offered_types(_,_,_,What) ->
+ orber:dbg("[~p] PullerSupplier:obtain_offered_types(~p);~n"
+ "Incorrect enumerant", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : validate_event_qos
+%% Arguments: RequiredQoS - CosNotification::QoSProperties
+%% Returns : ok | {'EXCEPTION', #'UnsupportedQoS'{}}
+%% AvilableQoS - CosNotification::NamedPropertyRangeSeq (out)
+%%-----------------------------------------------------------
+validate_event_qos(_OE_THIS, _OE_FROM, State, RequiredQoS) ->
+ AvilableQoS = 'CosNotification_Common':validate_event_qos(RequiredQoS,
+ ?get_LocalQoS(State)),
+ {reply, {ok, AvilableQoS}, State}.
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {NewQoS, LQS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ NewState = ?update_EventDB(State, LQS),
+ {reply, ok, ?set_BothQoS(NewState, NewQoS, LQS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS}
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotifyComm::NotifySubscribe ---------
+%%----------------------------------------------------------%
+%% function : subscription_change
+%% Arguments: Added - Removed - CosNotification::EventTypeSeq
+%% Returns : ok
+%%-----------------------------------------------------------
+subscription_change(_OE_THIS, _OE_FROM, State, Added, Removed) ->
+ cosNotification_Filter:validate_types(Added),
+ cosNotification_Filter:validate_types(Removed),
+ %% On this "side", we care about which type of events the client
+ %% will require, since the client (or an agent) clearly stated
+ %% that it's only interested in these types of events.
+ %% Also see PusherConsumer- and PullerConsumer-'offer_change'.
+ update_subscribe(remove, State, Removed),
+ CurrentSub = ?get_AllSubscribe(State),
+ NewState =
+ case cosNotification_Filter:check_types(Added++CurrentSub) of
+ true ->
+ %% Types supplied does in some way cause all events to be valid.
+ %% Smart? Would have been better to not supply any at all.
+ ?set_SubscribeData(State, true);
+ {ok, Which, WC} ->
+ ?set_SubscribeData(State, {Which, WC})
+ end,
+ update_subscribe(add, NewState, Added),
+ case ?get_SubscribeType(NewState) of
+ true ->
+ %% Perhaps we should handle exception here?!
+ %% Probably not. Better to stay "on-line".
+ catch 'CosNotifyComm_NotifyPublish':
+ offer_change(?get_Client(NewState), Added, Removed),
+ ok;
+ _->
+ ok
+ end,
+ {reply, ok, NewState}.
+
+update_subscribe(_, _, [])->
+ ok;
+update_subscribe(add, State, [H|T]) ->
+ ?add_Subscribe(State, H),
+ update_subscribe(add, State, T);
+update_subscribe(remove, State, [H|T]) ->
+ ?del_Subscribe(State, H),
+ update_subscribe(remove, State, T).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin -----------
+%%----------------------------------------------------------%
+%% function : add_filter
+%% Arguments: Filter - CosNotifyFilter::Filter
+%% Returns : FilterID - long
+%%-----------------------------------------------------------
+add_filter(_OE_THIS, _OE_FROM, State, Filter) ->
+ 'CosNotification_Common':type_check(Filter, 'CosNotifyFilter_Filter'),
+ FilterID = ?new_Id(State),
+ NewState = ?set_IdCounter(State, FilterID),
+ {reply, FilterID, ?add_Filter(NewState, FilterID, Filter)}.
+
+%%----------------------------------------------------------%
+%% function : remove_filter
+%% Arguments: FilterID - long
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ok, ?del_Filter(State, FilterID)};
+remove_filter(_,_,_,What) ->
+ orber:dbg("[~p] PullerSupplier:remove_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_filter
+%% Arguments: FilterID - long
+%% Returns : Filter - CosNotifyFilter::Filter |
+%% {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}
+%%-----------------------------------------------------------
+get_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ?get_Filter(State, FilterID), State};
+get_filter(_,_,_,What) ->
+ orber:dbg("[~p] PullerSupplier:get_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_filters
+%% Arguments: -
+%% Returns : Filter - CosNotifyFilter::FilterIDSeq
+%%-----------------------------------------------------------
+get_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_AllFilterID(State), State}.
+
+%%----------------------------------------------------------%
+%% function : remove_all_filters
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ok, ?del_AllFilter(State)}.
+
+%%----- Inherit from CosEventComm::PullSupplier -------------
+%%----------------------------------------------------------%
+%% function : disconnect_pull_supplier
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_pull_supplier(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----------------------------------------------------------%
+%% function : pull
+%% Arguments: -
+%% Returns : any - CORBA::ANY
+%%-----------------------------------------------------------
+pull(_OE_THIS, OE_FROM, State) when ?is_ANY(State) ->
+ case ?get_Event(State) of
+ {[], _} ->
+ {noreply, ?set_RespondTo(State, OE_FROM)};
+ {Event,_} ->
+ {reply, Event, State}
+ end;
+pull(_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : try_pull
+%% Arguments: -
+%% Returns : any - CORBA::ANY
+%% HasEvent - boolean (out-type)
+%%-----------------------------------------------------------
+try_pull(_OE_THIS, _OE_FROM, State) when ?is_ANY(State) ->
+ case ?get_Event(State) of
+ {[], _} ->
+ {reply, {any:create(orber_tc:null(), null), false}, State};
+ {Event, Bool} ->
+ {reply, {Event, Bool}, State}
+ end;
+try_pull(_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- Inherit from CosNotifyComm::SequencePullSupplier ----
+%%----------------------------------------------------------%
+%% function : disconnect_sequence_pull_supplier
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_sequence_pull_supplier(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----------------------------------------------------------%
+%% function : pull_structured_events
+%% Arguments: Max - long()
+%% Returns : [StructuredEvent, ..]
+%%-----------------------------------------------------------
+pull_structured_events(_OE_THIS, OE_FROM, State, Max) when ?is_SEQUENCE(State) ->
+ case ?is_BatchLimitReached(State, Max) of
+ true ->
+ %% This test is not fool-proof; if Events have been stored
+ %% using StartTime they will still be there but we cannot
+ %% deliver them anyway. To solve this "problem" would cost!
+ %% Hence, since it works fine otherwise it will do.
+ case ?get_Events(State, Max) of
+ {[], false} ->
+ NewState = start_timer(State),
+ {noreply, ?set_RespondTo(NewState, {OE_FROM, Max})};
+ {Event,_} ->
+ {reply, Event, State}
+ end;
+ _->
+ NewState = start_timer(State),
+ {noreply, ?set_RespondTo(NewState, {OE_FROM, Max})}
+ end;
+pull_structured_events(_,_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : try_pull_structured_events
+%% Arguments: Max - long()
+%% Returns : [StructuredEvent, ..]
+%% HasEvent - Boolean()
+%%-----------------------------------------------------------
+try_pull_structured_events(_OE_THIS, _OE_FROM, State, Max) when ?is_SEQUENCE(State) ->
+ {reply, ?get_Events(State, Max), State};
+try_pull_structured_events(_,_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- Inherit from CosNotifyComm::StructuredPullSupplier --
+%%----------------------------------------------------------%
+%% function : disconnect_structured_pull_supplier
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_structured_pull_supplier(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----------------------------------------------------------%
+%% function : pull_structured_event
+%% Arguments: -
+%% Returns :
+%%-----------------------------------------------------------
+pull_structured_event(_OE_THIS, OE_FROM, State) when ?is_STRUCTURED(State) ->
+ case ?get_Event(State) of
+ {[], _} ->
+ {noreply, ?set_RespondTo(State, OE_FROM)};
+ {Event,_} ->
+ {reply, Event, State}
+ end;
+pull_structured_event(_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : try_pull_structured_event
+%% Arguments: -
+%% Returns :
+%%-----------------------------------------------------------
+try_pull_structured_event(_OE_THIS, _OE_FROM, State) when ?is_STRUCTURED(State) ->
+ case ?get_Event(State) of
+ {[], _} ->
+ {reply,
+ {?not_CreateSE("","","",[],[],any:create(orber_tc:null(), null)), false},
+ State};
+ {Event, Bool} ->
+ {reply, {Event, Bool}, State}
+ end;
+try_pull_structured_event(_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj({value, {_, Obj}}) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}.
+
+find_ids(List) -> find_ids(List, []).
+find_ids([], Acc) -> Acc;
+find_ids([{I,_}|T], Acc) -> find_ids(T, [I|Acc]);
+find_ids(_, _) -> corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%% Delete a single object.
+%% The list do not differ, i.e., no filter removed, raise exception.
+delete_obj(List,List) -> corba:raise(#'CosNotifyFilter_FilterNotFound'{});
+delete_obj(List,_) -> List.
+
+
+%%-----------------------------------------------------------
+%% function : callSeq
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callSeq(_OE_THIS, OE_FROM, State, EventsIn, Status) ->
+ %% We should do something here, i.e., see what QoS this Object offers and
+ %% act accordingly.
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:validate_event(?get_SubscribeData(State), EventsIn,
+ ?get_AllFilter(State),
+ ?get_SubscribeDB(State),
+ Status) of
+ {[], _} ->
+ ?DBG("PROXY NOSUBSCRIPTION SEQUENCE/STRUCTURED: ~p~n",[EventsIn]),
+ {noreply, State};
+ %% Just one event and we got a client waiting => there is no need to store
+ %% the event, just transform it and pass it on.
+ {[Event], _} when ?is_ANY(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED SEQUENCE[1]==>ANY: ~p~n",[Event]),
+ AnyEvent = any:create('CosNotification_StructuredEvent':tc(),Event),
+ case ?addAndGet_Event(State, AnyEvent) of
+ {[], _} ->
+ ?DBG("PROXY RECEIVED UNDELIVERABLE SEQUENCE[1]: ~p~n",
+ [Event]),
+ %% Cannot deliver the event at the moment; perhaps Starttime
+ %% set or Deadline passed.
+ {noreply, State};
+ {PossiblyOtherEvent, _} ->
+ ?DBG("PROXY RECEIVED SEQUENCE[1] ~p; DELIVER: ~p~n",
+ [Event, PossiblyOtherEvent]),
+ corba:reply(?get_RespondTo(State), PossiblyOtherEvent),
+ {noreply, ?reset_RespondTo(State)}
+ end;
+ {[Event],_} when ?is_STRUCTURED(State), ?is_Waiting(State) ->
+ case ?addAndGet_Event(State, Event) of
+ {[], _} ->
+ ?DBG("PROXY RECEIVED UNDELIVERABLE SEQUENCE[1]: ~p~n",
+ [Event]),
+ %% Cannot deliver the event at the moment; perhaps Starttime
+ %% set or Deadline passed.
+ {noreply, State};
+ {PossiblyOtherEvent, _} ->
+ ?DBG("PROXY RECEIVED SEQUENCE[1] ~p; DELIVER: ~p~n",
+ [Event, PossiblyOtherEvent]),
+ corba:reply(?get_RespondTo(State), PossiblyOtherEvent),
+ {noreply, ?reset_RespondTo(State)}
+ end;
+ %% A sequence of events => store them and extract the first (according to QoS)
+ %% event and forward it.
+ {Events,_} when ?is_ANY(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED SEQUENCE==>ANY: ~p~n",[Events]),
+ store_events(State, Events),
+ case ?get_Event(State) of
+ {[], _} ->
+ {noreply, State};
+ {AnyEvent, _} ->
+ corba:reply(?get_RespondTo(State), AnyEvent),
+ {noreply, ?reset_RespondTo(State)}
+ end;
+ {Events, _} when ?is_STRUCTURED(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED SEQUENCE: ~p~n",[Events]),
+ store_events(State, Events),
+ case ?get_Event(State) of
+ {[], _} ->
+ {noreply, State};
+ {_StrEvent, _} ->
+ corba:reply(?get_RespondTo(State), Events),
+ {noreply, ?reset_RespondTo(State)}
+ end;
+ {Events, _} when ?is_SEQUENCE(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED SEQUENCE: ~p~n",[Events]),
+ %% Store them first and extract Max events in QoS order.
+ store_events(State, Events),
+ {RespondTo, Max} = ?get_RespondTo(State),
+ case ?is_BatchLimitReached(State, Max) of
+ true ->
+ {EventSeq, _} = ?get_Events(State, Max),
+ corba:reply(RespondTo, EventSeq),
+ stop_timer(State),
+ {noreply, ?reset_RespondTo(State)};
+ _->
+ {noreply, State}
+ end;
+ %% No client waiting. Store the event(s).
+ {Events, _} ->
+ ?DBG("PROXY RECEIVED SEQUENCE: ~p~n",[Events]),
+ store_events(State, Events),
+ {noreply, State}
+ end.
+
+store_events(_State, []) ->
+ ok;
+store_events(State, [Event|Rest]) when ?is_ANY(State) ->
+ AnyEvent = any:create('CosNotification_StructuredEvent':tc(),Event),
+ ?add_Event(State,AnyEvent),
+ store_events(State, Rest);
+store_events(State, [Event|Rest]) ->
+ ?add_Event(State,Event),
+ store_events(State, Rest).
+
+%%-----------------------------------------------------------
+%% function : callAny
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callAny(_OE_THIS, OE_FROM, State, EventIn, Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:validate_event(?get_SubscribeData(State), EventIn,
+ ?get_AllFilter(State),
+ ?get_SubscribeDB(State),
+ Status) of
+ {[],_} ->
+ ?DBG("PROXY NOSUBSCRIPTION ANY: ~p~n",[EventIn]),
+ {noreply, State};
+ {Event,_} when ?is_ANY(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED ANY: ~p~n",[Event]),
+ case ?addAndGet_Event(State, Event) of
+ {[],_} ->
+ %% Unable to deliver the event (Starttime, Deadline etc).
+ {noreply, State};
+ {MaybeOtherEvent , _} ->
+ corba:reply(?get_RespondTo(State), MaybeOtherEvent),
+ {noreply, ?reset_RespondTo(State)}
+ end;
+ {Event,_} when ?is_ANY(State) ->
+ ?DBG("PROXY RECEIVED ANY: ~p~n",[Event]),
+ ?add_Event(State,Event),
+ {noreply, State};
+ {Event,_} when ?is_STRUCTURED(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED ANY==>STRUCTURED: ~p~n",[Event]),
+ case ?addAndGet_Event(State, ?not_CreateSE("","%ANY","",[],[],Event)) of
+ {[],_} ->
+ %% Unable to deliver the event (Starttime, Deadline etc).
+ {noreply, State};
+ {MaybeOtherEvent , _} ->
+ corba:reply(?get_RespondTo(State), MaybeOtherEvent),
+ {noreply, ?reset_RespondTo(State)}
+ end;
+ {Event,_} when ?is_SEQUENCE(State), ?is_Waiting(State) ->
+ ?DBG("PROXY RECEIVED ANY==>SEQUENCE[1]: ~p~n",[Event]),
+ ?add_Event(State,?not_CreateSE("","%ANY","",[],[],Event)),
+ {RespondTo, Max} = ?get_RespondTo(State),
+ case ?is_BatchLimitReached(State, Max) of
+ true ->
+ {EventSeq, _} = ?get_Events(State, Max),
+ corba:reply(RespondTo, EventSeq),
+ stop_timer(State),
+ {noreply, ?reset_RespondTo(State)};
+ _ ->
+ {noreply, State}
+ end;
+ {Event,_} ->
+ ?DBG("PROXY RECEIVED ANY==>STRUCTURED/SEQUENCE: ~p~n",[Event]),
+ ?add_Event(State,?not_CreateSE("","%ANY","",[],[],Event)),
+ {noreply, State}
+ end.
+
+
+
+%% Start timers which send a message each time we should push events. Only used
+%% when this objects is defined to supply sequences.
+start_timer(State) ->
+ TS = now(),
+ case catch timer:send_after(timer:seconds(?get_PacingInterval(State)),
+ {pacing, TS}) of
+ {ok,PacTRef} ->
+ ?DBG("PULL SUPPLIER STARTED TIMER, BATCH LIMIT: ~p~n",
+ [?get_BatchLimit(State)]),
+ ?set_PacingTimer(State, {PacTRef, TS});
+ What ->
+ orber:dbg("[~p] PullerSupplier:start_timer();~n"
+ "Unable to invoke timer:send_interval/2: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+stop_timer(State) ->
+ case ?get_PacingTimer(State) of
+ undefined ->
+ ok;
+ {Timer, _} ->
+ ?DBG("PULL SUPPLIER STOPPED TIMER~n",[]),
+ timer:cancel(Timer)
+ end.
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/PusherConsumer_impl.erl b/lib/cosNotification/src/PusherConsumer_impl.erl
new file mode 100644
index 0000000000..195e81ec58
--- /dev/null
+++ b/lib/cosNotification/src/PusherConsumer_impl.erl
@@ -0,0 +1,729 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : PusherConsumer_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('PusherConsumer_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+-include_lib("cosEvent/include/CosEventComm.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::ProxyPushConsumer -------------
+-export([connect_any_push_supplier/4]).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPushConsumer -----
+-export([connect_sequence_push_supplier/4]).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPushConsumer ---
+-export([connect_structured_push_supplier/4]).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxyConsumer ----
+-export([obtain_subscription_types/4,
+ validate_event_qos/4]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotifyComm::NotifyPublish ------------
+-export([offer_change/5]).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin ------------
+-export([add_filter/4,
+ remove_filter/4,
+ get_filter/4,
+ get_all_filters/3,
+ remove_all_filters/3]).
+
+%%----- Inherit from CosEventComm::PushConsumer -------------
+-export([push/4,
+ disconnect_push_consumer/3]).
+
+%%----- Inherit from CosNotifyComm::SequencePushConsumer ----
+-export([push_structured_events/4,
+ disconnect_sequence_push_consumer/3]).
+
+%%----- Inherit from CosNotifyComm::StructuredPushConsumer --
+-export([push_structured_event/4,
+ disconnect_structured_push_consumer/3]).
+
+%%----- Inherit from CosEventChannelAdmin::ProxyPushConsumer
+-export([connect_push_supplier/4]).
+
+%% Attributes (external) CosNotifyChannelAdmin::ProxySupplier
+-export(['_get_MyType'/3,
+ '_get_MyAdmin'/3]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {myType,
+ myAdmin,
+ myAdminPid,
+ myChannel,
+ myFilters = [],
+ myOperator,
+ idCounter = 0,
+ client,
+ qosGlobal,
+ qosLocal,
+ publishType = false,
+ etsR,
+ eventDB}).
+
+%% Data structures constructors
+-define(get_InitState(_MyT, _MyA, _MyAP, _QS, _LQS, _Ch, _EDB, _MyOP),
+ #state{myType = _MyT,
+ myAdmin = _MyA,
+ myAdminPid= _MyAP,
+ myChannel = _Ch,
+ myOperator= _MyOP,
+ qosGlobal = _QS,
+ qosLocal = _LQS,
+ etsR = ets:new(oe_ets, [set, protected]),
+ eventDB = _EDB}).
+
+%%-------------- Data structures selectors -----------------
+%% Attributes
+-define(get_MyType(S), S#state.myType).
+-define(get_MyAdmin(S), S#state.myAdmin).
+-define(get_MyAdminPid(S), S#state.myAdminPid).
+-define(get_MyChannel(S), S#state.myChannel).
+-define(get_MyOperator(S), S#state.myOperator).
+%% Client Object
+-define(get_Client(S), S#state.client).
+%% QoS
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+%% Filters
+-define(get_Filter(S, I), find_obj(lists:keysearch(I, 1, S#state.myFilters))).
+-define(get_AllFilter(S), S#state.myFilters).
+-define(get_AllFilterID(S), find_ids(S#state.myFilters)).
+%% Publish
+-define(get_AllPublish(S), lists:flatten(ets:match(S#state.etsR,
+ {'$1',publish}))).
+-define(get_PublishType(S), S#state.publishType).
+%% ID
+-define(get_IdCounter(S), S#state.idCounter).
+%% Event
+-define(get_Event(S), cosNotification_eventDB:get_event(S#state.eventDB)).
+-define(get_Events(S,M), cosNotification_eventDB:get_events(S#state.eventDB, M)).
+
+-define(get_EventCounter(S), S#state.eventCounter).
+%% Admin
+-define(get_BatchLimit(S), ?not_GetMaximumBatchSize((S#state.qosLocal))).
+
+%%-------------- Data structures modifiers -----------------
+%% Client Object
+-define(set_Client(S,D), S#state{client=D}).
+-define(del_Client(S), S#state{client=undefined}).
+-define(set_Unconnected(S), S#state{client=undefined}).
+%% QoS
+-define(set_LocalQoS(S,D), S#state{qosLocal=D}).
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+%% Filters
+-define(add_Filter(S,I,O), S#state{myFilters=[{I,O}|S#state.myFilters]}).
+-define(del_Filter(S,I), S#state{myFilters=
+ delete_obj(lists:keydelete(I, 1, S#state.myFilters),
+ S#state.myFilters)}).
+-define(del_AllFilter(S), S#state{myFilters=[]}).
+%% Publish
+-define(add_Publish(S,E), ets:insert(S#state.etsR, {E, publish})).
+-define(del_Publish(S,E), ets:delete(S#state.etsR, E)).
+-define(set_PublishType(S,T), S#state{publishType=T}).
+%% ID
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+%% Event
+-define(add_Event(S,E), cosNotification_eventDB:add_event(S#state.eventDB, E)).
+-define(update_EventDB(S,Q), S#state{eventDB=
+ cosNotification_eventDB:update(S#state.eventDB, Q)}).
+
+-define(set_EventCounter(S,V), S#state{eventCounter=V}).
+-define(add_to_EventCounter(S,V),S#state{eventCounter=S#state.eventCounter+V}).
+-define(reset_EventCounter(S), S#state{eventCounter=0}).
+-define(increase_EventCounter(S),S#state{eventCounter=(S#state.eventCounter+1)}).
+-define(decrease_EventCounter(S),S#state{eventCounter=S#state.eventCounter-1}).
+-define(add_ToEventCounter(S,A), S#state{eventCounter=(S#state.eventCounter+A)}).
+-define(sub_FromEventCounter(S,_A), S#state{eventCounter=(S#state.eventCounter-_A)}).
+-define(set_EventCounterTo(S,V), S#state{eventCounter=V}).
+
+%% MISC
+-define(is_ANY(S), S#state.myType == 'PUSH_ANY').
+-define(is_STRUCTURED(S), S#state.myType == 'PUSH_STRUCTURED').
+-define(is_SEQUENCE(S), S#state.myType == 'PUSH_SEQUENCE').
+-define(is_ANDOP(S), S#state.myOperator == 'AND_OP').
+-define(is_UnConnected(S), S#state.client == undefined).
+-define(is_Connected(S), S#state.client =/= undefined).
+-define(is_PersistentConnection(S),
+ ?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_PersistentEvent(S),
+ ?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent).
+-define(is_BatchLimitReached(S), S#state.eventCounter >=
+ ?not_GetMaximumBatchSize((S#state.qosLocal))).
+
+
+%%----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%-----------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?DBG("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, Reason} when ?get_MyAdminPid(State)==Pid->
+ ?DBG("PARENT ADMIN: ~p TERMINATED.~n",[Reason]),
+ {stop, Reason, State};
+ {'EXIT', _Pid, _Reason} ->
+ ?DBG("PROXYPUSHCONSUMER: ~p TERMINATED.~n",[_Reason]),
+ {noreply, State};
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init(['PUSH_SEQUENCE', MyAdmin, MyAdminPid, InitQoS, LQS,
+ MyChannel, Options, Operator]) ->
+ process_flag(trap_exit, true),
+ %% Only if MyType is 'PUSH_SEQUENCE' we need an ets to store events in.
+ %% Otherwise we'll forward them at once. Why? We don't know when the next event
+ %% is due.
+ GCTime = 'CosNotification_Common':get_option(gcTime, Options,
+ ?not_DEFAULT_SETTINGS),
+ GCLimit = 'CosNotification_Common':get_option(gcLimit, Options,
+ ?not_DEFAULT_SETTINGS),
+ TimeRef = 'CosNotification_Common':get_option(timeService, Options,
+ ?not_DEFAULT_SETTINGS),
+ {ok, ?get_InitState('PUSH_SEQUENCE', MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel,
+ cosNotification_eventDB:create_db(LQS, GCTime, GCLimit, TimeRef),
+ Operator)};
+init([MyType, MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel, _Options, Operator]) ->
+ process_flag(trap_exit, true),
+ {ok, ?get_InitState(MyType, MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel,
+ undefined, Operator)}.
+
+terminate(_Reason, State) when ?is_UnConnected(State) ->
+ ok;
+terminate(_Reason, State) ->
+ Client = ?get_Client(State),
+ case catch corba_object:is_nil(Client) of
+ false when ?is_ANY(State) ->
+ 'CosNotification_Common':disconnect('CosEventComm_PushSupplier',
+ disconnect_push_supplier,
+ Client);
+ false when ?is_SEQUENCE(State) ->
+ 'CosNotification_Common':disconnect('CosNotifyComm_SequencePushSupplier',
+ disconnect_sequence_push_supplier,
+ Client);
+ false when ?is_STRUCTURED(State) ->
+ 'CosNotification_Common':disconnect('CosNotifyComm_StructuredPushSupplier',
+ disconnect_structured_push_supplier,
+ Client);
+ _ ->
+ ok
+ end.
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_ProxyConsumer attributes ------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyType'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyType'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyType(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyAdmin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyAdmin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyAdmin(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----- CosEventChannelAdmin::ProxyPushConsumer -------------
+%%----------------------------------------------------------%
+%% function : connect_push_supplier
+%% Arguments: Client - CosEventComm::PushSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%% Both exceptions from CosEventChannelAdmin!!!
+%%-----------------------------------------------------------
+connect_push_supplier(OE_THIS, OE_FROM, State, Client) ->
+ connect_any_push_supplier(OE_THIS, OE_FROM, State, Client).
+
+%%----- CosNotifyChannelAdmin::ProxyPushConsumer ------------
+%%----------------------------------------------------------%
+%% function : connect_any_push_supplier
+%% Arguments: Client - CosEventComm::PushSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%% Both exceptions from CosEventChannelAdmin!!!
+%%-----------------------------------------------------------
+connect_any_push_supplier(_OE_THIS, _OE_FROM, State, Client) when ?is_ANY(State) ->
+ ?not_TypeCheck(Client, 'CosEventComm_PushSupplier'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, ?set_Client(State, Client)}
+ end;
+connect_any_push_supplier(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPushConsumer ----
+%%----------------------------------------------------------%
+%% function : connect_sequence_push_supplier
+%% Arguments: Client - CosNotifyComm::SequencePushSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%%-----------------------------------------------------------
+connect_sequence_push_supplier(_OE_THIS, _OE_FROM, State, Client) when ?is_SEQUENCE(State) ->
+ ?not_TypeCheck(Client, 'CosNotifyComm_SequencePushSupplier'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, ?set_Client(State, Client)}
+ end;
+connect_sequence_push_supplier(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPushConsumer --
+%%----------------------------------------------------------%
+%% function : connect_structured_push_supplier
+%% Arguments: Client - CosNotifyComm::StructuredPushSupplier
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%%-----------------------------------------------------------
+connect_structured_push_supplier(_OE_THIS, _OE_FROM, State, Client) when ?is_STRUCTURED(State) ->
+ ?not_TypeCheck(Client, 'CosNotifyComm_StructuredPushSupplier'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, ?set_Client(State, Client)}
+ end;
+connect_structured_push_supplier(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxyConsumer ---
+%%----------------------------------------------------------%
+%% function : obtain_subscription_types
+%% Arguments: Mode - enum 'ObtainInfoMode' (CosNotifyChannelAdmin)
+%% Returns : CosNotification::EventTypeSeq
+%%-----------------------------------------------------------
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_OFF') ->
+ {reply, ?get_AllPublish(State), ?set_PublishType(State, false)};
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_ON') ->
+ {reply, ?get_AllPublish(State), ?set_PublishType(State, true)};
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_OFF') ->
+ {reply, [], ?set_PublishType(State, false)};
+obtain_subscription_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_ON') ->
+ {reply, [], ?set_PublishType(State, true)};
+obtain_subscription_types(_,_,_,What) ->
+ orber:dbg("[~p] PusherConsumer:obtain_subscription_types(~p);~n"
+ "Incorrect enumerant", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : validate_event_qos
+%% Arguments: RequiredQoS - CosNotification::QoSProperties
+%% Returns : ok | {'EXCEPTION', #'UnsupportedQoS'{}}
+%% AvilableQoS - CosNotification::NamedPropertyRangeSeq (out)
+%%-----------------------------------------------------------
+validate_event_qos(_OE_THIS, _OE_FROM, State, RequiredQoS) ->
+ AvilableQoS = 'CosNotification_Common':validate_event_qos(RequiredQoS,
+ ?get_LocalQoS(State)),
+ {reply, {ok, AvilableQoS}, State}.
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {NewQoS, LQS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ NewState = ?update_EventDB(State, LQS),
+ {reply, ok, ?set_BothQoS(NewState, NewQoS, LQS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS}
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotifyComm::NotifyPublish -----------
+%%----------------------------------------------------------%
+%% function : offer_change
+%% Arguments: Added - #'CosNotification_EventType'{}
+%% Removed - #'CosNotification_EventType'{}
+%% Returns : ok |
+%% {'EXCEPTION', #'CosNotifyComm_InvalidEventType'{}}
+%%-----------------------------------------------------------
+offer_change(_OE_THIS, _OE_FROM, State, Added, Removed) ->
+ cosNotification_Filter:validate_types(Added),
+ cosNotification_Filter:validate_types(Removed),
+ %% On this "side" we don't really care about which
+ %% type of events the client will supply.
+ %% Perhaps, later on, if we want to check this against Filters
+ %% associated with this object we may change this approach, i.e., if
+ %% the filter will not allow passing certain event types. But the
+ %% user should see to that that situation never occurs. It would add
+ %% extra overhead. Also see PusherSupplier- and PullerSuppler-
+ %% 'subscription_change'.
+ update_publish(add, State, Added),
+ update_publish(remove, State, Removed),
+ case ?get_PublishType(State) of
+ true ->
+ %% Perhaps we should handle exception here?!
+ %% Probably not. Better to stay "on-line".
+ catch 'CosNotifyComm_NotifySubscribe':
+ subscription_change(?get_Client(State), Added, Removed),
+ ok;
+ _->
+ ok
+ end,
+ {reply, ok, State}.
+
+update_publish(_, _, [])->
+ ok;
+update_publish(add, State, [H|T]) ->
+ ?add_Publish(State, H),
+ update_publish(add, State, T);
+update_publish(remove, State, [H|T]) ->
+ ?del_Publish(State, H),
+ update_publish(remove, State, T).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin -----------
+%%----------------------------------------------------------%
+%% function : add_filter
+%% Arguments: Filter - CosNotifyFilter::Filter
+%% Returns : FilterID - long
+%%-----------------------------------------------------------
+add_filter(_OE_THIS, _OE_FROM, State, Filter) ->
+ 'CosNotification_Common':type_check(Filter, 'CosNotifyFilter_Filter'),
+ FilterID = ?new_Id(State),
+ NewState = ?set_IdCounter(State, FilterID),
+ {reply, FilterID, ?add_Filter(NewState, FilterID, Filter)}.
+
+%%----------------------------------------------------------%
+%% function : remove_filter
+%% Arguments: FilterID - long
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ok, ?del_Filter(State, FilterID)};
+remove_filter(_,_,_,What) ->
+ orber:dbg("[~p] PusherConsumer:remove_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_filter
+%% Arguments: FilterID - long
+%% Returns : Filter - CosNotifyFilter::Filter |
+%% {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}
+%%-----------------------------------------------------------
+get_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ?get_Filter(State, FilterID), State};
+get_filter(_,_,_,What) ->
+ orber:dbg("[~p] PusherConsumer:get_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_filters
+%% Arguments: -
+%% Returns : Filter - CosNotifyFilter::FilterIDSeq
+%%-----------------------------------------------------------
+get_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_AllFilterID(State), State}.
+
+%%----------------------------------------------------------%
+%% function : remove_all_filters
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ok, ?del_AllFilter(State)}.
+
+%%----- Inherit from CosEventComm::PushConsumer -------------
+%%----------------------------------------------------------%
+%% function : disconnect_push_consumer
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_push_consumer(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----------------------------------------------------------%
+%% function : push
+%% Arguments: AnyEvent
+%% Returns : ok |
+%%-----------------------------------------------------------
+push(OE_THIS, OE_FROM, State, Event) when ?is_ANY(State) ->
+ corba:reply(OE_FROM, ok),
+ case {?not_isConvertedStructured(Event),
+ cosNotification_eventDB:filter_events([Event], ?get_AllFilter(State))} of
+ {_, {[],_}} when ?is_ANDOP(State) ->
+ {noreply, State};
+ {true, {[],[_]}} ->
+ %% Is OR and converted, change back and forward to Admin
+ forward(seq, ?get_MyAdmin(State), State, [any:get_value(Event)],
+ 'MATCH', OE_THIS);
+ {_, {[],[_]}} ->
+ %% Is OR and not converted, forward to Admin
+ forward(any, ?get_MyAdmin(State), State, Event, 'MATCH', OE_THIS);
+ {true, {[_],_}} when ?is_ANDOP(State) ->
+ %% Is AND and converted, change back and forward to Admin
+ forward(seq, ?get_MyAdmin(State), State, [any:get_value(Event)],
+ 'MATCH', OE_THIS);
+ {true, {[_],_}} ->
+ %% Is OR and converted, change back and forward to Channel
+ forward(seq, ?get_MyChannel(State), State, [any:get_value(Event)],
+ 'MATCHED', OE_THIS);
+ {_, {[_],_}} when ?is_ANDOP(State) ->
+ %% Is AND and not converted, forward to Admin
+ forward(any, ?get_MyAdmin(State), State, Event, 'MATCH', OE_THIS);
+ _ ->
+ %% Is OR and not converted, forward to Channel
+ forward(any, ?get_MyChannel(State), State, Event, 'MATCHED', OE_THIS)
+ end;
+push(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- Inherit from CosNotifyComm::SequencePushConsumer ----
+%%----------------------------------------------------------%
+%% function : disconnect_sequence_push_consumer
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_sequence_push_consumer(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----------------------------------------------------------%
+%% function : push_structured_events
+%% Arguments: CosNotification::EventBatch
+%% Returns : ok |
+%%-----------------------------------------------------------
+push_structured_events(OE_THIS, OE_FROM, State, Events) when ?is_SEQUENCE(State) ->
+ corba:reply(OE_FROM, ok),
+ %% We cannot convert parts of the sequence to any, event though they
+ %% are converted from any to structured. Would be 'impossible' to send.
+ case cosNotification_eventDB:filter_events(Events, ?get_AllFilter(State)) of
+ {[],_} when ?is_ANDOP(State) ->
+ {noreply, State};
+ {[],Failed} ->
+ forward(seq, ?get_MyAdmin(State), State, Failed, 'MATCH', OE_THIS);
+ {Passed, _} when ?is_ANDOP(State) ->
+ forward(seq, ?get_MyAdmin(State), State, Passed, 'MATCH', OE_THIS);
+ {Passed, []} ->
+ forward(seq, ?get_MyChannel(State), State, Passed, 'MATCHED', OE_THIS);
+ {Passed, Failed} ->
+ %% Is OR, send Passed to channel and Failed to Admin.
+ forward(seq, ?get_MyChannel(State), State, Passed, 'MATCHED', OE_THIS),
+ forward(seq, ?get_MyAdmin(State), State, Failed, 'MATCH', OE_THIS)
+ end;
+push_structured_events(_,_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- Inherit from CosNotifyComm::StructuredPushConsumer --
+%%----------------------------------------------------------%
+%% function : disconnect_structured_push_consumer
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_structured_push_consumer(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----------------------------------------------------------%
+%% function : push_structured_event
+%% Arguments: CosNotification::StructuredEvent
+%% Returns : ok |
+%%-----------------------------------------------------------
+push_structured_event(OE_THIS, OE_FROM, State, Event) when ?is_STRUCTURED(State) ->
+ corba:reply(OE_FROM, ok),
+ case {?not_isConvertedAny(Event),
+ cosNotification_eventDB:filter_events([Event], ?get_AllFilter(State))} of
+ {_, {[],_}} when ?is_ANDOP(State) ->
+ {noreply, State};
+ {true, {[],[_]}} ->
+ %% Is OR and converted, change back and forward to Admin
+ forward(any, ?get_MyAdmin(State), State,
+ Event#'CosNotification_StructuredEvent'.remainder_of_body,
+ 'MATCH', OE_THIS);
+ {_, {[],[_]}} ->
+ %% Is OR and not converted, forward to Admin
+ forward(seq, ?get_MyAdmin(State), State, [Event], 'MATCH', OE_THIS);
+ {true, {[_],_}} when ?is_ANDOP(State) ->
+ %% Is AND and converted, change back and forward to Admin
+ forward(any, ?get_MyAdmin(State), State,
+ Event#'CosNotification_StructuredEvent'.remainder_of_body,
+ 'MATCH', OE_THIS);
+ {true, {[_],_}} ->
+ %% Is OR and converted, change back and forward to Channel
+ forward(any, ?get_MyChannel(State), State,
+ Event#'CosNotification_StructuredEvent'.remainder_of_body,
+ 'MATCHED', OE_THIS);
+ {_, {[_],_}} when ?is_ANDOP(State) ->
+ %% Is AND and not converted, forward to Admin
+ forward(seq, ?get_MyAdmin(State), State, [Event], 'MATCH', OE_THIS);
+ _ ->
+ %% Is OR and not converted, forward to Channel
+ forward(seq, ?get_MyChannel(State), State, [Event], 'MATCHED', OE_THIS)
+ end;
+push_structured_event(_,_,_,_) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj({value, {_, Obj}}) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}.
+
+find_ids(List) -> find_ids(List, []).
+find_ids([], Acc) -> Acc;
+find_ids([{I,_}|T], Acc) -> find_ids(T, [I|Acc]);
+find_ids(What, _) ->
+ orber:dbg("[~p] PusherConsumer:find_ids();~n"
+ "Id corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%% Delete a single object.
+%% The list don not differ, i.e., no filter removed, raise exception.
+delete_obj(List,List) -> corba:raise(#'CosNotifyFilter_FilterNotFound'{});
+delete_obj(List,_) -> List.
+
+%% Forward events
+forward(any, SendTo, State, Event, Status, OE_THIS) ->
+ case catch oe_CosNotificationComm_Event:callAny(SendTo, Event, Status) of
+ ok ->
+ ?DBG("PROXY FORWARD ANY: ~p~n",[Event]),
+ {noreply, State};
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ orber:dbg("[~p] PusherConsumer:forward();~n"
+ "Admin/Channel no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, OE_THIS},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PusherConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Dropping: ~p", [?LINE, R, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ R ->
+ orber:dbg("[~p] PusherConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, R, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, OE_THIS},
+ {client, ?get_Client(State)},
+ {reason, R}]),
+ {stop, normal, State}
+ end;
+forward(seq, SendTo, State, Event, Status, OE_THIS) ->
+ case catch oe_CosNotificationComm_Event:callSeq(SendTo, Event, Status) of
+ ok ->
+ {noreply, State};
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ ?DBG("ADMIN NO LONGER EXIST; DROPPING: ~p~n", [Event]),
+ 'CosNotification_Common':notify([{proxy, OE_THIS},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ R when ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PusherConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Dropping: ~p", [?LINE, R, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ R ->
+ orber:dbg("[~p] PusherConsumer:forward();~n"
+ "Admin/Channel respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, R, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, OE_THIS},
+ {client, ?get_Client(State)},
+ {reason, R}]),
+ {stop, normal, State}
+ end.
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/PusherSupplier_impl.erl b/lib/cosNotification/src/PusherSupplier_impl.erl
new file mode 100644
index 0000000000..51949b8c46
--- /dev/null
+++ b/lib/cosNotification/src/PusherSupplier_impl.erl
@@ -0,0 +1,1052 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : PusherSupplier_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('PusherSupplier_impl').
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% cosEvent files.
+-include_lib("cosEvent/include/CosEventChannelAdmin.hrl").
+-include_lib("cosEvent/include/CosEventComm.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%%----- CosNotifyChannelAdmin::ProxyPushSupplier -------------
+-export([connect_any_push_consumer/4]).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPushSupplier ---
+-export([connect_structured_push_consumer/4]).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPushSupplier -----
+-export([connect_sequence_push_consumer/4]).
+
+%%----- CosNotifyChannelAdmin::*ProxyPushSupplier ------------
+-export([suspend_connection/3,
+ resume_connection/3]).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxySupplier ----
+-export([obtain_offered_types/4,
+ validate_event_qos/4]).
+
+%%----- Inherit from CosNotification::QoSAdmin ---------------
+-export([get_qos/3,
+ set_qos/4,
+ validate_qos/4]).
+
+%%----- Inherit from CosNotifyComm::NotifySubscribe ----------
+-export([subscription_change/5]).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin ------------
+-export([add_filter/4,
+ remove_filter/4,
+ get_filter/4,
+ get_all_filters/3,
+ remove_all_filters/3]).
+
+%%----- Inherit from CosEventComm::PushSupplier -------------
+-export([disconnect_push_supplier/3]).
+
+%%----- Inherit from CosNotifyComm::StructuredPushSupplier --
+-export([disconnect_structured_push_supplier/3]).
+
+%%----- Inherit from CosNotifyComm::SequencePushSupplier ----
+-export([disconnect_sequence_push_supplier/3]).
+
+%%----- Inherit from CosEventChannelAdmin::ProxyPushSupplier
+-export([connect_push_consumer/4]).
+
+%% Attributes (external) CosNotifyChannelAdmin::ProxySupplier
+-export(['_get_MyType'/3,
+ '_get_MyAdmin'/3,
+ '_get_priority_filter'/3,
+ '_set_priority_filter'/4,
+ '_get_lifetime_filter'/3,
+ '_set_lifetime_filter'/4]).
+
+%%--------------- Internal -----------------------------------
+%%----- Inherit from cosNotificationComm ---------------------
+-export([callAny/5,
+ callSeq/5]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+%%--------------- LOCAL DEFINITIONS --------------------------
+%% Data structures
+-record(state, {myType,
+ myAdmin,
+ myAdminPid,
+ myChannel,
+ myFilters = [],
+ myOperator,
+ idCounter = 0,
+ prioFil,
+ lifetFil,
+ client,
+ qosGlobal,
+ qosLocal,
+ suspended = false,
+ pacingTimer,
+ subscribeType = false,
+ subscribeData = true,
+ etsR,
+ eventDB,
+ this,
+ maxCache,
+ cacheTimeout,
+ cacheInterval}).
+
+%% Data structures constructors
+-define(get_InitState(_MyT, _MyA, _MyAP, _QS, _LQS, _Ch, _MyOp, _GT, _GL, _TR),
+ #state{myType = _MyT,
+ myAdmin = _MyA,
+ myAdminPid= _MyAP,
+ qosGlobal = _QS,
+ qosLocal = _LQS,
+ myChannel = _Ch,
+ myOperator=_MyOp,
+ etsR = ets:new(oe_ets, [set, protected]),
+ eventDB = cosNotification_eventDB:create_db(_LQS, _GT, _GL, _TR),
+ maxCache = cosNotificationApp:max_events()}).
+
+%% Data structures selectors
+%%-------------- Data structures selectors -----------------
+%% Attributes
+-define(get_MyType(S), S#state.myType).
+-define(get_MyAdmin(S), S#state.myAdmin).
+-define(get_MyAdminPid(S), S#state.myAdminPid).
+-define(get_MyChannel(S), S#state.myChannel).
+-define(get_MyOperator(S), S#state.myOperator).
+-define(get_PrioFil(S), S#state.prioFil).
+-define(get_LifeTFil(S), S#state.lifetFil).
+%% Client Object
+-define(get_Client(S), S#state.client).
+%% QoS
+-define(get_GlobalQoS(S), S#state.qosGlobal).
+-define(get_LocalQoS(S), S#state.qosLocal).
+-define(get_BothQoS(S), {S#state.qosGlobal, S#state.qosLocal}).
+%% Filters
+-define(get_Filter(S, I), find_obj(lists:keysearch(I, 1, S#state.myFilters))).
+-define(get_AllFilter(S), S#state.myFilters).
+-define(get_AllFilterID(S), find_ids(S#state.myFilters)).
+%% Amin
+-define(get_PacingTimer(S), S#state.pacingTimer).
+-define(get_PacingInterval(S), round(?not_GetPacingInterval((S#state.qosLocal))/10000000)).
+-define(get_BatchLimit(S), ?not_GetMaximumBatchSize((S#state.qosLocal))).
+%% Subscribe
+-define(get_AllSubscribe(S), lists:flatten(ets:match(S#state.etsR,
+ {'$1',subscribe}))).
+-define(get_SubscribeType(S), S#state.subscribeType).
+-define(get_SubscribeData(S), S#state.subscribeData).
+%% ID
+-define(get_IdCounter(S), S#state.idCounter).
+-define(get_SubscribeDB(S), S#state.etsR).
+%% Event
+-define(is_PersistentConnection(S),
+ (?not_GetConnectionReliability((S#state.qosLocal)) == ?not_Persistent)).
+-define(is_PersistentEvent(S),
+ (?not_GetEventReliability((S#state.qosLocal)) == ?not_Persistent)).
+
+-define(get_Event(S), cosNotification_eventDB:get_event(S#state.eventDB,
+ false)).
+% (not ?is_PersistentEvent(S)))).
+-define(get_Events(S,M), cosNotification_eventDB:get_events(S#state.eventDB, M, false)).
+% (not ?is_PersistentEvent(S)))).
+
+%%-------------- Data structures modifiers -----------------
+%% Attributes
+-define(set_PrioFil(S,D), S#state{prioFil=D}).
+-define(set_LifeTFil(S,D), S#state{lifetFil=D}).
+%% Client Object
+-define(set_Client(S,D), S#state{client=D}).
+-define(del_Client(S), S#state{client=undefined}).
+-define(set_Unconnected(S), S#state{client=undefined}).
+-define(set_Suspended(S), S#state{suspended=true}).
+-define(set_NotSuspended(S), S#state{suspended=false}).
+%% QoS
+-define(set_LocalQoS(S,D), S#state{qosLocal=D}).
+-define(set_GlobalQoS(S,D), S#state{qosGlobal=D}).
+-define(set_BothQoS(S,GD,LD), S#state{qosGlobal=GD, qosLocal=LD}).
+%% Filters
+-define(add_Filter(S,I,O), S#state{myFilters=[{I,O}|S#state.myFilters]}).
+-define(del_Filter(S,I), S#state{myFilters=
+ delete_obj(lists:keydelete(I, 1, S#state.myFilters),
+ S#state.myFilters)}).
+-define(del_AllFilter(S), S#state{myFilters=[]}).
+%% Admin
+-define(set_PacingTimer(S,T), S#state{pacingTimer=T}).
+%% Publish
+%% Subscribe
+-define(add_Subscribe(S,E), ets:insert(S#state.etsR, {E, subscribe})).
+-define(del_Subscribe(S,E), ets:delete(S#state.etsR, E)).
+-define(set_SubscribeType(S,T), S#state{subscribeType=T}).
+-define(set_SubscribeData(S,D), S#state{subscribeData=D}).
+%% ID
+-define(set_IdCounter(S,V), S#state{idCounter=V}).
+-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)).
+%% Events
+-define(add_Event(S,E), catch cosNotification_eventDB:
+ add_event(S#state.eventDB, E, S#state.lifetFil, S#state.prioFil)).
+-define(addAndGet_Event(S,E), catch cosNotification_eventDB:
+ add_and_get_event(S#state.eventDB, E, S#state.lifetFil, S#state.prioFil,
+ false)).
+% ?is_PersistentEvent(S))).
+-define(update_EventDB(S,Q), S#state{eventDB=
+ cosNotification_eventDB:update(S#state.eventDB, Q)}).
+
+
+%%-------------- MISC ----------------------------------------
+-define(is_ANY(S), S#state.myType == 'PUSH_ANY').
+-define(is_STRUCTURED(S), S#state.myType == 'PUSH_STRUCTURED').
+-define(is_SEQUENCE(S), S#state.myType == 'PUSH_SEQUENCE').
+-define(is_ANDOP(S), S#state.myOperator == 'AND_OP').
+-define(is_UnConnected(S), S#state.client == undefined).
+-define(is_Connected(S), S#state.client =/= undefined).
+-define(is_Suspended(S), S#state.suspended == true).
+-define(is_NotSuspended(S), S#state.suspended == false).
+-define(is_BatchLimitReached(S), cosNotification_eventDB:status(S#state.eventDB,
+ {batchLimit,
+ ?not_GetMaximumBatchSize((S#state.qosLocal))})).
+-define(has_Filters(S), S#state.myFilters =/= []).
+
+%%----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%-----------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, #state{cacheTimeout = Timeout,
+ cacheInterval = Interval} = State) ->
+ ?DBG("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, Reason} when ?get_MyAdminPid(State)==Pid ->
+ ?DBG("PARENT ADMIN: ~p TERMINATED.~n",[Reason]),
+ {stop, Reason, State};
+ {'EXIT', _Pid, _Reason} ->
+ ?DBG("PROXYPUSHSUPPLIER: ~p TERMINATED.~n",[_Reason]),
+ {noreply, State};
+ pacing ->
+ lookup_and_push(State, true);
+ cacheInterval ->
+ lookup_and_push(State, true);
+ cacheTimeout when Timeout == undefined, Interval == undefined ->
+ %% Late message, do not terminate
+ {noreply, State};
+ cacheTimeout ->
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, State#state.client},
+ {reason,
+ {timer, "Reached upper limit"}}]),
+ {stop, normal, State};
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([MyType, MyAdmin, MyAdminPid, InitQoS, LQS, MyChannel, Options, Operator]) ->
+ process_flag(trap_exit, true),
+ GCTime = 'CosNotification_Common':get_option(gcTime, Options,
+ ?not_DEFAULT_SETTINGS),
+ GCLimit = 'CosNotification_Common':get_option(gcLimit, Options,
+ ?not_DEFAULT_SETTINGS),
+ TimeRef = 'CosNotification_Common':get_option(timeService, Options,
+ ?not_DEFAULT_SETTINGS),
+ timer:start(),
+ {ok, ?get_InitState(MyType, MyAdmin, MyAdminPid,
+ InitQoS, LQS, MyChannel, Operator, GCTime, GCLimit, TimeRef)}.
+
+terminate(_Reason, State) when ?is_UnConnected(State) ->
+ stop_timer(State#state.cacheTimeout),
+ stop_timer(State#state.cacheInterval),
+ stop_timer(State#state.pacingTimer),
+ %% We are not connected to a Client. Hence, no need to invoke disconnect.
+ ok;
+terminate(_Reason, State) when ?is_ANY(State) ->
+ stop_timer(State#state.cacheTimeout),
+ stop_timer(State#state.cacheInterval),
+ stop_timer(State#state.pacingTimer),
+ 'CosNotification_Common':disconnect('CosEventComm_PushConsumer',
+ disconnect_push_consumer,
+ ?get_Client(State));
+terminate(_Reason, State) when ?is_SEQUENCE(State) ->
+ stop_timer(State#state.cacheTimeout),
+ stop_timer(State#state.cacheInterval),
+ stop_timer(State#state.pacingTimer),
+ 'CosNotification_Common':disconnect('CosNotifyComm_SequencePushConsumer',
+ disconnect_sequence_push_consumer,
+ ?get_Client(State));
+terminate(_Reason, State) when ?is_STRUCTURED(State) ->
+ stop_timer(State#state.cacheTimeout),
+ stop_timer(State#state.cacheInterval),
+ stop_timer(State#state.pacingTimer),
+ 'CosNotification_Common':disconnect('CosNotifyComm_StructuredPushConsumer',
+ disconnect_structured_push_consumer,
+ ?get_Client(State)).
+
+%%-----------------------------------------------------------
+%%----- CosNotifyChannelAdmin_ProxySupplier attributes ------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyType'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyType'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyType(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_get_MyAdmin'
+%% Type : readonly
+%% Returns :
+%%-----------------------------------------------------------
+'_get_MyAdmin'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_MyAdmin(State), State}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_*et_priority_filter'
+%% Type : read/write
+%% Returns :
+%%-----------------------------------------------------------
+'_get_priority_filter'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_PrioFil(State), State}.
+'_set_priority_filter'(_OE_THIS, _OE_FROM, State, PrioF) ->
+ {reply, ok, ?set_PrioFil(State, PrioF)}.
+
+%%----------------------------------------------------------%
+%% Attribute: '_*et_lifetime_filter'
+%% Type : read/write
+%% Returns :
+%%-----------------------------------------------------------
+'_get_lifetime_filter'(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_LifeTFil(State), State}.
+'_set_lifetime_filter'(_OE_THIS, _OE_FROM, State, LifeTF) ->
+ {reply, ok, ?set_LifeTFil(State, LifeTF)}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----- CosEventChannelAdmin::ProxyPushSupplier -------------
+%%----------------------------------------------------------%
+%% function : connect_push_consumer
+%% Arguments: Client - CosEventComm::PushConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%% Both exceptions from CosEventChannelAdmin!!!!
+%%-----------------------------------------------------------
+connect_push_consumer(OE_THIS, OE_FROM, State, Client) ->
+ connect_any_push_consumer(OE_THIS, OE_FROM, State, Client).
+
+%%----- CosNotifyChannelAdmin::ProxyPushSupplier ------------
+%%----------------------------------------------------------%
+%% function : connect_any_push_consumer
+%% Arguments: Client - CosEventComm::PushConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%% Both exceptions from CosEventChannelAdmin!!!!
+%%-----------------------------------------------------------
+connect_any_push_consumer(OE_THIS, _OE_FROM, State, Client) when ?is_ANY(State) ->
+ 'CosNotification_Common':type_check(Client, 'CosEventComm_PushConsumer'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, State#state{client = Client, this = OE_THIS}}
+ end;
+connect_any_push_consumer(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::SequenceProxyPushSupplier ----
+%%----------------------------------------------------------%
+%% function : connect_sequence_push_consumer
+%% Arguments: Client - CosNotifyComm::SequencePushConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%%-----------------------------------------------------------
+connect_sequence_push_consumer(OE_THIS, _OE_FROM, State, Client) when ?is_SEQUENCE(State) ->
+ 'CosNotification_Common':type_check(Client,
+ 'CosNotifyComm_SequencePushConsumer'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ NewState = start_timer(State),
+ {reply, ok, NewState#state{client = Client, this = OE_THIS}}
+ end;
+connect_sequence_push_consumer(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::StructuredProxyPushSupplier ---
+%%----------------------------------------------------------%
+%% function : connect_structured_push_consumer
+%% Arguments: Client - CosNotifyComm::StructuredPushConsumer
+%% Returns : ok | {'EXCEPTION', #'AlreadyConnected'{}} |
+%% {'EXCEPTION', #'TypeError'{}}
+%%-----------------------------------------------------------
+connect_structured_push_consumer(OE_THIS, _OE_FROM, State, Client) when ?is_STRUCTURED(State) ->
+ 'CosNotification_Common':type_check(Client,
+ 'CosNotifyComm_StructuredPushConsumer'),
+ if
+ ?is_Connected(State) ->
+ corba:raise(#'CosEventChannelAdmin_AlreadyConnected'{});
+ true ->
+ {reply, ok, State#state{client = Client, this = OE_THIS}}
+ end;
+connect_structured_push_consumer(_, _, _, _) ->
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----- CosNotifyChannelAdmin::*ProxyPushSupplier -----------
+%%----------------------------------------------------------%
+%% function : suspend_connection
+%% Arguments:
+%% Returns : ok | {'EXCEPTION', #'ConnectionAlreadyInactive'{}} |
+%% {'EXCEPTION', #'NotConneced'{}}
+%%-----------------------------------------------------------
+suspend_connection(_OE_THIS, _OE_FROM, State) when ?is_Connected(State) ->
+ if
+ ?is_Suspended(State) ->
+ corba:raise(#'CosNotifyChannelAdmin_ConnectionAlreadyInactive'{});
+ true ->
+ stop_timer(State#state.pacingTimer),
+ {reply, ok, State#state{pacingTimer = undefined,
+ suspended=true}}
+ end;
+suspend_connection(_,_,_)->
+ corba:raise(#'CosNotifyChannelAdmin_NotConnected'{}).
+
+%%----------------------------------------------------------%
+%% function : resume_connection
+%% Arguments:
+%% Returns : ok | {'EXCEPTION', #'ConnectionAlreadyActive'{}} |
+%% {'EXCEPTION', #'NotConneced'{}}
+%%-----------------------------------------------------------
+resume_connection(_OE_THIS, OE_FROM, State) when ?is_Connected(State) ->
+ if
+ ?is_NotSuspended(State) ->
+ corba:raise(#'CosNotifyChannelAdmin_ConnectionAlreadyActive'{});
+ true ->
+ corba:reply(OE_FROM, ok),
+ if
+ ?is_SEQUENCE(State) ->
+ start_timer(State);
+ true ->
+ ok
+ end,
+ lookup_and_push(?set_NotSuspended(State))
+ end;
+resume_connection(_,_,_) ->
+ corba:raise(#'CosNotifyChannelAdmin_NotConnected'{}).
+
+%%----- Inherit from CosNotifyChannelAdmin::ProxySupplier ---
+%%----------------------------------------------------------%
+%% function : obtain_offered_types
+%% Arguments: Mode - enum 'ObtainInfoMode' (CosNotifyChannelAdmin)
+%% Returns : CosNotification::EventTypeSeq
+%%-----------------------------------------------------------
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_OFF') ->
+ {reply, ?get_AllSubscribe(State), ?set_SubscribeType(State, false)};
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'ALL_NOW_UPDATES_ON') ->
+ {reply, ?get_AllSubscribe(State), ?set_SubscribeType(State, true)};
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_OFF') ->
+ {reply, [], ?set_SubscribeType(State, false)};
+obtain_offered_types(_OE_THIS, _OE_FROM, State, 'NONE_NOW_UPDATES_ON') ->
+ {reply, [], ?set_SubscribeType(State, true)};
+obtain_offered_types(_,_,_,What) ->
+ orber:dbg("[~p] PusherSupplier:obtain_offered_types(~p);~n"
+ "Bad enumerant", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_OPERATION'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : validate_event_qos
+%% Arguments: RequiredQoS - CosNotification::QoSProperties
+%% Returns : ok | {'EXCEPTION', #'UnsupportedQoS'{}}
+%% AvilableQoS - CosNotification::NamedPropertyRangeSeq (out)
+%%-----------------------------------------------------------
+validate_event_qos(_OE_THIS, _OE_FROM, State, RequiredQoS) ->
+ AvilableQoS = 'CosNotification_Common':validate_event_qos(RequiredQoS,
+ ?get_LocalQoS(State)),
+ {reply, {ok, AvilableQoS}, State}.
+
+%%----- Inherit from CosNotification::QoSAdmin --------------
+%%----------------------------------------------------------%
+%% function : get_qos
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+get_qos(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_GlobalQoS(State), State}.
+
+%%----------------------------------------------------------%
+%% function : set_qos
+%% Arguments: QoS - CosNotification::QoSProperties, i.e.,
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : ok | {'EXCEPTION', CosNotification::UnsupportedQoS}
+%%-----------------------------------------------------------
+set_qos(_OE_THIS, _OE_FROM, State, QoS) ->
+ {NewQoS, LQS} = 'CosNotification_Common':set_qos(QoS, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ NewState = ?update_EventDB(State, LQS),
+ {reply, ok, ?set_BothQoS(NewState, NewQoS, LQS)}.
+
+%%----------------------------------------------------------%
+%% function : validate_qos
+%% Arguments: Required_qos - CosNotification::QoSProperties
+%% [#'Property'{name, value}, ...] where name eq. string()
+%% and value eq. any().
+%% Returns : {'EXCEPTION', CosNotification::UnsupportedQoS}
+%% {ok, CosNotification::NamedPropertyRangeSeq}
+%%-----------------------------------------------------------
+validate_qos(_OE_THIS, _OE_FROM, State, Required_qos) ->
+ QoS = 'CosNotification_Common':validate_qos(Required_qos, ?get_BothQoS(State),
+ proxy, ?get_MyAdmin(State),
+ false),
+ {reply, {ok, QoS}, State}.
+
+%%----- Inherit from CosNotifyComm::NotifySubscribe ---------
+%%----------------------------------------------------------%
+%% function : subscription_change
+%% Arguments: Added - #'CosNotification_EventType'{}
+%% Removed - #'CosNotification_EventType'{}
+%% Returns : ok |
+%% {'EXCEPTION', #'CosNotifyComm_InvalidEventType'{}}
+%%-----------------------------------------------------------
+subscription_change(_OE_THIS, _OE_FROM, State, Added, Removed) ->
+ cosNotification_Filter:validate_types(Added),
+ cosNotification_Filter:validate_types(Removed),
+ %% On this "side", we care about which type of events the client
+ %% will require, since the client (or an agent) clearly stated
+ %% that it's only interested in these types of events.
+ %% Also see PusherConsumer- and PullerConsumer-'offer_change'.
+ update_subscribe(remove, State, Removed),
+ CurrentSub = ?get_AllSubscribe(State),
+ NewState =
+ case cosNotification_Filter:check_types(Added++CurrentSub) of
+ true ->
+ %% Types supplied does in some way cause all events to be valid.
+ %% Smart? Would have been better to not supply any at all.
+ ?set_SubscribeData(State, true);
+ {ok, Which, WC} ->
+ ?set_SubscribeData(State, {Which, WC})
+ end,
+ update_subscribe(add, NewState, Added),
+ case ?get_SubscribeType(NewState) of
+ true ->
+ %% Perhaps we should handle exception here?!
+ %% Probably not. Better to stay "on-line".
+ catch 'CosNotifyComm_NotifyPublish':
+ offer_change(?get_Client(NewState), Added, Removed),
+ ok;
+ _->
+ ok
+ end,
+ {reply, ok, NewState}.
+
+update_subscribe(_, _, [])->
+ ok;
+update_subscribe(add, State, [H|T]) ->
+ ?add_Subscribe(State, H),
+ update_subscribe(add, State, T);
+update_subscribe(remove, State, [H|T]) ->
+ ?del_Subscribe(State, H),
+ update_subscribe(remove, State, T).
+
+%%----- Inherit from CosNotifyFilter::FilterAdmin -----------
+%%----------------------------------------------------------%
+%% function : add_filter
+%% Arguments: Filter - CosNotifyFilter::Filter
+%% Returns : FilterID - long
+%%-----------------------------------------------------------
+add_filter(_OE_THIS, _OE_FROM, State, Filter) ->
+ 'CosNotification_Common':type_check(Filter, 'CosNotifyFilter_Filter'),
+ FilterID = ?new_Id(State),
+ NewState = ?set_IdCounter(State, FilterID),
+ {reply, FilterID, ?add_Filter(NewState, FilterID, Filter)}.
+
+%%----------------------------------------------------------%
+%% function : remove_filter
+%% Arguments: FilterID - long
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ok, ?del_Filter(State, FilterID)};
+remove_filter(_,_,_,What) ->
+ orber:dbg("[~p] PusherSupplier:remove_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_filter
+%% Arguments: FilterID - long
+%% Returns : Filter - CosNotifyFilter::Filter |
+%% {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}
+%%-----------------------------------------------------------
+get_filter(_OE_THIS, _OE_FROM, State, FilterID) when is_integer(FilterID) ->
+ {reply, ?get_Filter(State, FilterID), State};
+get_filter(_,_,_,What) ->
+ orber:dbg("[~p] PusherSupplier:get_filter(~p); Not an integer",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : get_all_filters
+%% Arguments: -
+%% Returns : Filter - CosNotifyFilter::FilterIDSeq
+%%-----------------------------------------------------------
+get_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ?get_AllFilterID(State), State}.
+
+%%----------------------------------------------------------%
+%% function : remove_all_filters
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+remove_all_filters(_OE_THIS, _OE_FROM, State) ->
+ {reply, ok, ?del_AllFilter(State)}.
+
+
+%%----- Inherit from CosEventComm::PushSupplier -------------
+%%----------------------------------------------------------%
+%% function : disconnect_push_supplier
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_push_supplier(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----- Inherit from CosNotifyComm::StructuredPushSupplier --
+%%----------------------------------------------------------%
+%% function : disconnect_structured_push_supplier
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_structured_push_supplier(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%----- Inherit from CosNotifyComm::SequencePushSupplier ----
+%%----------------------------------------------------------%
+%% function : disconnect_sequence_push_supplier
+%% Arguments: -
+%% Returns : ok
+%%-----------------------------------------------------------
+disconnect_sequence_push_supplier(_OE_THIS, _OE_FROM, State) ->
+ {stop, normal, ok, ?set_Unconnected(State)}.
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+find_obj({value, {_, Obj}}) -> Obj;
+find_obj(_) -> {'EXCEPTION', #'CosNotifyFilter_FilterNotFound'{}}.
+
+find_ids(List) -> find_ids(List, []).
+find_ids([], Acc) -> Acc;
+find_ids([{I,_}|T], Acc) -> find_ids(T, [I|Acc]);
+find_ids(What, _) ->
+ orber:dbg("[~p] PusherSupplier:find_ids();~n"
+ "Id corrupt: ~p", [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%% Delete a single object.
+%% The list do not differ, i.e., no filter removed, raise exception.
+delete_obj(List,List) -> corba:raise(#'CosNotifyFilter_FilterNotFound'{});
+delete_obj(List,_) -> List.
+
+%%-----------------------------------------------------------
+%% function : callSeq
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callSeq(_OE_THIS, OE_FROM, State, EventsIn, Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:validate_event(?get_SubscribeData(State), EventsIn,
+ ?get_AllFilter(State),
+ ?get_SubscribeDB(State),
+ Status) of
+ {[],_} ->
+ ?DBG("PROXY NOSUBSCRIPTION SEQUENCE/STRUCTURED: ~p~n",[EventsIn]),
+ {noreply, State};
+ {Events,_} when ?is_Suspended(State) ->
+ store_events(State, Events),
+ {noreply, State};
+ {Events,_} when ?is_UnConnected(State) ->
+ orber:dbg("[~p] PusherSupplier:callAny();~n"
+ "Not connected, dropping event(s): ~p",
+ [?LINE, Events], ?DEBUG_LEVEL),
+ {noreply, State};
+ {[Event],_} when ?is_STRUCTURED(State) ->
+ ?DBG("PROXY RECEIVED SEQUENCE: ~p~n",[Event]),
+ empty_db(State, ?addAndGet_Event(State, Event));
+ {[Event],_} when ?is_ANY(State) ->
+ ?DBG("PROXY RECEIVED SEQUENCE: ~p~n",[Event]),
+ AnyEvent = any:create('CosNotification_StructuredEvent':tc(),Event),
+ empty_db(State, ?addAndGet_Event(State, AnyEvent));
+ {Events,_} ->
+ ?DBG("PROXY RECEIVED SEQUENCE: ~p~n",[Events]),
+ store_events(State, Events),
+ lookup_and_push(State)
+ end.
+
+%%-----------------------------------------------------------
+%% function : callAny
+%% Arguments:
+%% Returns :
+%%-----------------------------------------------------------
+callAny(_OE_THIS, OE_FROM, State, EventIn, Status) ->
+ corba:reply(OE_FROM, ok),
+ case cosNotification_eventDB:validate_event(?get_SubscribeData(State), EventIn,
+ ?get_AllFilter(State),
+ ?get_SubscribeDB(State),
+ Status) of
+ {[],_} ->
+ ?DBG("PROXY NOSUBSCRIPTION ANY: ~p~n",[EventIn]),
+ %% To be on the safe side, test if there are any events that not
+ %% have been forwarded (should only be possible if StartTime is used).
+ lookup_and_push(State);
+ {Event,_} when ?is_Suspended(State), ?is_ANY(State) ->
+ ?add_Event(State, Event),
+ {noreply, State};
+ {Event,_} when ?is_Suspended(State) ->
+ ?add_Event(State, ?not_CreateSE("","%ANY","",[],[],Event)),
+ {noreply, State};
+ {Event,_} when ?is_UnConnected(State) ->
+ orber:dbg("[~p] PusherSupplier:callAny();~n"
+ "Not connected, dropping event: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ {noreply, State};
+ {Event,_} when ?is_ANY(State) ->
+ ?DBG("PROXY RECEIVED ANY: ~p~n",[Event]),
+ %% We must store the event since there may be other events that should
+ %% be delivered first, e.g., higher priority.
+ empty_db(State, ?addAndGet_Event(State, Event));
+ {Event,_} when ?is_SEQUENCE(State) ->
+ ?DBG("PROXY RECEIVED ANY==>SEQUENCE: ~p~n",[Event]),
+ StrEvent = ?not_CreateSE("","%ANY","",[],[],Event),
+ ?add_Event(State, StrEvent),
+ lookup_and_push(State);
+ {Event,_} ->
+ ?DBG("PROXY RECEIVED ANY==>STRUCTURED: ~p~n",[Event]),
+ StrEvent = ?not_CreateSE("","%ANY","",[],[],Event),
+ empty_db(State, ?addAndGet_Event(State, StrEvent))
+ end.
+
+%% Lookup and push "the correct" amount of events.
+lookup_and_push(State) ->
+ %% The boolean indicates, if false, that we will only push events if we have
+ %% passed the BatchLimit. If true we will ignore this limit and push events
+ %% anyway (typcially invoked when pacing limit passed).
+ lookup_and_push(State, false).
+lookup_and_push(State, false) when ?is_SEQUENCE(State) ->
+ case ?is_BatchLimitReached(State) of
+ true ->
+ case ?get_Events(State, ?get_BatchLimit(State)) of
+ {[], _, _} ->
+ ?DBG("BATCHLIMIT (~p) REACHED BUT NO EVENTS FOUND~n",
+ [?get_BatchLimit(State)]),
+ {noreply, State};
+ {Events, _, Keys} ->
+ ?DBG("BATCHLIMIT (~p) REACHED, EVENTS FOUND: ~p~n",
+ [?get_BatchLimit(State), Events]),
+ case catch 'CosNotifyComm_SequencePushConsumer':
+ push_structured_events(?get_Client(State), Events) of
+ ok ->
+ cosNotification_eventDB:delete_events(Keys),
+ lookup_and_push(reset_cache(State), false);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ ?DBG("PUSH SUPPLIER CLIENT NO LONGER EXIST~n", []),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ What when ?is_PersistentEvent(State),
+ ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ check_cache(State);
+ What when ?is_PersistentConnection(State) ->
+ %% Here we should do something when we want to handle
+ %% Persistent EventReliability.
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p~n"
+ "Dropping events: ~p",
+ [?LINE, What, Events], ?DEBUG_LEVEL),
+ cosNotification_eventDB:delete_events(Keys),
+ {noreply, State};
+ WhatII ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p~n"
+ "Terminating and dropping events: ~p",
+ [?LINE, WhatII, Events], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, WhatII}]),
+ {stop, normal, State}
+ end
+ end;
+ _ ->
+ ?DBG("BATCHLIMIT (~p) NOT REACHED~n",[?get_BatchLimit(State)]),
+ {noreply, State}
+ end;
+lookup_and_push(State, true) when ?is_SEQUENCE(State) ->
+ case ?get_Events(State, ?get_BatchLimit(State)) of
+ {[], _, _} ->
+ ?DBG("PACELIMIT REACHED BUT NO EVENTS FOUND~n", []),
+ {noreply, State};
+ {Events, _, Keys} ->
+ ?DBG("PACELIMIT REACHED, EVENTS FOUND: ~p~n", [Events]),
+ case catch 'CosNotifyComm_SequencePushConsumer':
+ push_structured_events(?get_Client(State), Events) of
+ ok ->
+ cosNotification_eventDB:delete_events(Keys),
+ lookup_and_push(reset_cache(State), false);
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client no longer exists; terminating and dropping events: ~p",
+ [?LINE, Events], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ What when ?is_PersistentEvent(State),
+ ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ check_cache(State);
+ What when ?is_PersistentConnection(State) ->
+ %% Here we should do something when we want to handle
+ %% Persistent EventReliability.
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p~n"
+ "Dropping events: ~p",
+ [?LINE, What, Events], ?DEBUG_LEVEL),
+ cosNotification_eventDB:delete_events(Keys),
+ {noreply, State};
+ WhatII ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p~n"
+ "Terminating and dropping events: ~p",
+ [?LINE, WhatII, Events], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, WhatII}]),
+ {stop, normal, State}
+ end
+ end;
+lookup_and_push(State, _) ->
+ empty_db(State, ?get_Event(State)).
+
+
+%% Push all events stored while not connected or received in sequence.
+empty_db(State, {[], _, _}) ->
+ {noreply, State};
+empty_db(State, {Event, _, Keys}) when ?is_STRUCTURED(State) ->
+ case catch 'CosNotifyComm_StructuredPushConsumer':
+ push_structured_event(?get_Client(State), Event) of
+ ok ->
+ cosNotification_eventDB:delete_events(Keys),
+ NewState = reset_cache(State),
+ empty_db(NewState, ?get_Event(NewState));
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ orber:dbg("[~p] PusherSupplier:empty_db();~n"
+ "Client no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ What when ?is_PersistentEvent(State),
+ ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ check_cache(State);
+ What when ?is_PersistentConnection(State) ->
+ %% Here we should do something when we want to handle
+ %% Persistent EventReliability.
+ orber:dbg("[~p] PusherSupplier:empty_db();~n"
+ "Client respond incorrect: ~p~n"
+ "Dropping event: ~p",
+ [?LINE, What, Event], ?DEBUG_LEVEL),
+ cosNotification_eventDB:delete_events(Keys),
+ {noreply, State};
+ WhatII ->
+ orber:dbg("[~p] PusherSupplier:empty_db();~n"
+ "Client respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, WhatII, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, WhatII}]),
+ {stop, normal, State}
+ end;
+empty_db(State, {Event, _, Keys}) when ?is_ANY(State) ->
+ case catch 'CosEventComm_PushConsumer':push(?get_Client(State), Event) of
+ ok ->
+ cosNotification_eventDB:delete_events(Keys),
+ NewState = reset_cache(State),
+ empty_db(NewState, ?get_Event(NewState));
+ {'EXCEPTION', E} when is_record(E, 'OBJECT_NOT_EXIST') orelse
+ is_record(E, 'NO_PERMISSION') orelse
+ is_record(E, 'CosEventComm_Disconnected') ->
+ orber:dbg("[~p] PusherSupplier:empty_db();~n"
+ "Client no longer exists; terminating and dropping: ~p",
+ [?LINE, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, {'EXCEPTION', E}}]),
+ {stop, normal, State};
+ What when ?is_PersistentEvent(State),
+ ?is_PersistentConnection(State) ->
+ orber:dbg("[~p] PusherSupplier:lookup_and_push();~n"
+ "Client respond incorrect: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ check_cache(State);
+ What when ?is_PersistentConnection(State) ->
+ %% Here we should do something when we want to handle
+ %% Persistent EventReliability.
+ orber:dbg("[~p] PusherSupplier:empty_db();~n"
+ "Client respond incorrect: ~p~n"
+ "Dropping Event: ~p",
+ [?LINE, What, Event], ?DEBUG_LEVEL),
+ cosNotification_eventDB:delete_events(Keys),
+ {noreply, State};
+ WhatII ->
+ orber:dbg("[~p] PusherSupplier:empty_db();~n"
+ "Client respond incorrect: ~p~n"
+ "Terminating and dropping: ~p",
+ [?LINE, WhatII, Event], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, ?get_Client(State)},
+ {reason, WhatII}]),
+ {stop, normal, State}
+ end.
+
+reset_cache(#state{cacheTimeout = undefined,
+ cacheInterval = undefined} = State) ->
+ State;
+reset_cache(State) ->
+ stop_timer(State#state.cacheTimeout),
+ stop_timer(State#state.cacheInterval),
+ State#state{cacheTimeout = undefined,
+ cacheInterval = undefined}.
+
+check_cache(#state{maxCache = Max, cacheTimeout = Timeout,
+ cacheInterval = Interval} = State) ->
+ case cosNotification_eventDB:status(State#state.eventDB, eventCounter) of
+ Count when Count > Max ->
+ %% Reached the upper limit, terminate.
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, State#state.client},
+ {reason, {max_events, Max}}]),
+ {stop, normal, State};
+ _ when Timeout == undefined, Interval == undefined ->
+ case {timer:send_interval(cosNotificationApp:interval_events(),
+ cacheInterval),
+ timer:send_after(cosNotificationApp:timeout_events(),
+ cacheTimeout)} of
+ {{ok, IntervalRef}, {ok, TimeoutRef}} ->
+ {noreply, State#state{cacheTimeout = TimeoutRef,
+ cacheInterval = IntervalRef}};
+ Error ->
+ orber:dbg("[~p] PusherSupplier:check_cache();~n"
+ "Unable to start timers: ~p",
+ [?LINE, Error], ?DEBUG_LEVEL),
+ 'CosNotification_Common':notify([{proxy, State#state.this},
+ {client, State#state.client},
+ {reason, {timer, Error}}]),
+ {stop, normal, State}
+ end;
+ _ ->
+ %% Timers already started.
+ {noreply, State}
+ end.
+
+store_events(_State, []) ->
+ ok;
+store_events(State, [Event|Rest]) when ?is_ANY(State) ->
+ AnyEvent = any:create('CosNotification_StructuredEvent':tc(),Event),
+ ?add_Event(State, AnyEvent),
+ store_events(State, Rest);
+store_events(State, [Event|Rest]) ->
+ ?add_Event(State, Event),
+ store_events(State, Rest).
+
+%% Start timers which send a message each time we should push events. Only used
+%% when this objects is defined to supply sequences.
+start_timer(State) ->
+ case ?get_PacingInterval(State) of
+ 0 ->
+ ?DBG("PUSH SUPPLIER STARTED NO TIMER (0), BATCH LIMIT: ~p~n",
+ [?get_BatchLimit(State)]),
+
+ State;
+ PacInt ->
+ case catch timer:send_interval(timer:seconds(PacInt), pacing) of
+ {ok,PacTRef} ->
+ ?DBG("PUSH SUPPLIER STARTED TIMER, BATCH LIMIT: ~p~n",
+ [?get_BatchLimit(State)]),
+ ?set_PacingTimer(State, PacTRef);
+ What ->
+ orber:dbg("[~p] PusherSupplier:start_timer();~n"
+ "Unable to invoke timer:send_interval/2: ~p",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end
+ end.
+
+stop_timer(undefined) ->
+ ?DBG("PUSH SUPPLIER HAVE NO TIMER TO STOP~n",[]),
+ ok;
+stop_timer(Timer) ->
+ ?DBG("PUSH SUPPLIER STOPPED TIMER~n",[]),
+ timer:cancel(Timer),
+ ok.
+
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/cosNotification.app.src b/lib/cosNotification/src/cosNotification.app.src
new file mode 100644
index 0000000000..04beac36e8
--- /dev/null
+++ b/lib/cosNotification/src/cosNotification.app.src
@@ -0,0 +1,120 @@
+{application, cosNotification,
+ [{description, "The Erlang CosNotification application"},
+ {vsn, "%VSN%"},
+ {modules,
+ [
+ 'CosNotification_Common',
+ 'CosNotifyChannelAdmin_ConsumerAdmin_impl',
+ 'CosNotifyChannelAdmin_EventChannelFactory_impl',
+ 'CosNotifyChannelAdmin_EventChannel_impl',
+ 'CosNotifyChannelAdmin_SupplierAdmin_impl',
+ 'PullerConsumer_impl',
+ 'PullerSupplier_impl',
+ 'PusherConsumer_impl',
+ 'PusherSupplier_impl',
+ 'cosNotificationApp',
+ 'CosNotifyFilter_Filter_impl',
+ 'CosNotifyFilter_MappingFilter_impl',
+ 'CosNotifyFilter_FilterFactory_impl',
+ 'cosNotification_Scanner',
+ 'cosNotification_Grammar',
+ 'cosNotification_Filter',
+ 'cosNotification_eventDB',
+ 'oe_CosNotification',
+ 'oe_cosNotificationAppComm',
+ 'oe_CosNotificationComm_Event',
+ 'CosNotification',
+ 'CosNotification_AdminPropertiesAdmin',
+ 'CosNotification_EventHeader',
+ 'CosNotification_EventType',
+ 'CosNotification_FixedEventHeader',
+ 'CosNotification_NamedPropertyRange',
+ 'CosNotification_Property',
+ 'CosNotification_PropertyError',
+ 'CosNotification_PropertyRange',
+ 'CosNotification_QoSAdmin',
+ 'CosNotification_StructuredEvent',
+ 'CosNotification_UnsupportedAdmin',
+ 'CosNotification_UnsupportedQoS',
+ 'CosNotification_EventBatch',
+ 'CosNotification_EventTypeSeq',
+ 'CosNotification_NamedPropertyRangeSeq',
+ 'CosNotification_PropertyErrorSeq',
+ 'CosNotification_PropertySeq',
+ 'oe_CosNotifyChannelAdmin',
+ 'CosNotifyChannelAdmin_AdminLimit',
+ 'CosNotifyChannelAdmin_AdminLimitExceeded',
+ 'CosNotifyChannelAdmin_AdminNotFound',
+ 'CosNotifyChannelAdmin_ChannelNotFound',
+ 'CosNotifyChannelAdmin_ConnectionAlreadyActive',
+ 'CosNotifyChannelAdmin_ConnectionAlreadyInactive',
+ 'CosNotifyChannelAdmin_ConsumerAdmin',
+ 'CosNotifyChannelAdmin_EventChannel',
+ 'CosNotifyChannelAdmin_EventChannelFactory',
+ 'CosNotifyChannelAdmin_NotConnected',
+ 'CosNotifyChannelAdmin_ProxyConsumer',
+ 'CosNotifyChannelAdmin_ProxyNotFound',
+ 'CosNotifyChannelAdmin_ProxyPullConsumer',
+ 'CosNotifyChannelAdmin_ProxyPullSupplier',
+ 'CosNotifyChannelAdmin_ProxyPushConsumer',
+ 'CosNotifyChannelAdmin_ProxyPushSupplier',
+ 'CosNotifyChannelAdmin_ProxySupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPullConsumer',
+ 'CosNotifyChannelAdmin_SequenceProxyPullSupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPushConsumer',
+ 'CosNotifyChannelAdmin_SequenceProxyPushSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPullConsumer',
+ 'CosNotifyChannelAdmin_StructuredProxyPullSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPushConsumer',
+ 'CosNotifyChannelAdmin_StructuredProxyPushSupplier',
+ 'CosNotifyChannelAdmin_SupplierAdmin',
+ 'CosNotifyChannelAdmin_AdminIDSeq',
+ 'CosNotifyChannelAdmin_ChannelIDSeq',
+ 'CosNotifyChannelAdmin_ProxyIDSeq',
+ 'oe_CosNotifyComm',
+ 'CosNotifyComm_InvalidEventType',
+ 'CosNotifyComm_NotifyPublish',
+ 'CosNotifyComm_NotifySubscribe',
+ 'CosNotifyComm_PullConsumer',
+ 'CosNotifyComm_PullSupplier',
+ 'CosNotifyComm_PushConsumer',
+ 'CosNotifyComm_PushSupplier',
+ 'CosNotifyComm_SequencePullConsumer',
+ 'CosNotifyComm_SequencePullSupplier',
+ 'CosNotifyComm_SequencePushConsumer',
+ 'CosNotifyComm_SequencePushSupplier',
+ 'CosNotifyComm_StructuredPullConsumer',
+ 'CosNotifyComm_StructuredPullSupplier',
+ 'CosNotifyComm_StructuredPushConsumer',
+ 'CosNotifyComm_StructuredPushSupplier',
+ 'oe_CosNotifyFilter',
+ 'CosNotifyFilter_CallbackNotFound',
+ 'CosNotifyFilter_ConstraintExp',
+ 'CosNotifyFilter_ConstraintInfo',
+ 'CosNotifyFilter_ConstraintNotFound',
+ 'CosNotifyFilter_DuplicateConstraintID',
+ 'CosNotifyFilter_Filter',
+ 'CosNotifyFilter_FilterAdmin',
+ 'CosNotifyFilter_FilterFactory',
+ 'CosNotifyFilter_FilterNotFound',
+ 'CosNotifyFilter_InvalidConstraint',
+ 'CosNotifyFilter_InvalidGrammar',
+ 'CosNotifyFilter_InvalidValue',
+ 'CosNotifyFilter_MappingConstraintInfo',
+ 'CosNotifyFilter_MappingConstraintPair',
+ 'CosNotifyFilter_MappingFilter',
+ 'CosNotifyFilter_UnsupportedFilterableData',
+ 'CosNotifyFilter_CallbackIDSeq',
+ 'CosNotifyFilter_ConstraintExpSeq',
+ 'CosNotifyFilter_ConstraintIDSeq',
+ 'CosNotifyFilter_ConstraintInfoSeq',
+ 'CosNotifyFilter_FilterIDSeq',
+ 'CosNotifyFilter_MappingConstraintInfoSeq',
+ 'CosNotifyFilter_MappingConstraintPairSeq'
+ ]
+ },
+ {registered, [cosNotificationSup, oe_cosNotificationFactory]},
+ {applications, [orber, stdlib, kernel]},
+ {env, []},
+ {mod, {cosNotificationApp, []}}
+]}.
diff --git a/lib/cosNotification/src/cosNotification.appup.src b/lib/cosNotification/src/cosNotification.appup.src
new file mode 100644
index 0000000000..6c3b2833b7
--- /dev/null
+++ b/lib/cosNotification/src/cosNotification.appup.src
@@ -0,0 +1,7 @@
+{"%VSN%",
+ [
+ ],
+ [
+ ]
+}.
+
diff --git a/lib/cosNotification/src/cosNotificationApp.erl b/lib/cosNotification/src/cosNotificationApp.erl
new file mode 100644
index 0000000000..ba44163272
--- /dev/null
+++ b/lib/cosNotification/src/cosNotificationApp.erl
@@ -0,0 +1,447 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : cosNotificationApp.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module(cosNotificationApp).
+
+%%--------------- INCLUDES -----------------------------------
+%% Local
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+%%--------------- EXPORTS-------------------------------------
+%% cosNotification API external
+-export([start/0, stop/0,
+ start_factory/1, start_factory/0, stop_factory/1,
+ start_global_factory/0, start_global_factory/1,
+ start_filter_factory/1, start_filter_factory/0, stop_filter_factory/1,
+ install/0, install/1, uninstall/0, uninstall/1,
+ install_event/0, install_event/1, uninstall_event/0, uninstall_event/1,
+ install_typed/0, install_typed/1, uninstall_typed/0, uninstall_typed/1,
+ create_structured_event/6, type_check/0, notify/0, max_events/0,
+ timeout_events/0, interval_events/0]).
+
+%% Application callbacks
+-export([start/2, init/1, stop/1]).
+
+%%--------------- DEFINES ------------------------------------
+-define(IDL_MODULES, ['oe_CosNotification',
+ 'oe_cosNotificationAppComm',
+ 'oe_CosNotifyComm',
+ 'oe_CosNotifyFilter',
+ 'oe_CosNotifyChannelAdmin']).
+-define(EVENT_IDL_MODULES, ['oe_CosEventComm',
+ 'oe_CosEventChannelAdmin']).
+-define(TYPED_IDL_MODULES, ['oe_CosTypedEvent',
+ 'oe_CosTypedNotification']).
+
+-define(FACTORY_NAME, oe_cosNotificationFactory).
+-define(SUPERVISOR_NAME, cosNotificationSup).
+
+
+%%------------------------------------------------------------
+%% function : install/X
+%% Arguments: - | Time (seconds)
+%% Returns : ok | EXIT | EXCEPTION
+%% Effect : Install necessary data in the IFR DB
+%%------------------------------------------------------------
+
+install() ->
+ install(0).
+
+install(Time) when is_integer(Time) ->
+ install_loop(?IDL_MODULES, timer:seconds(Time));
+install(_Time) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%------------------------------------------------------------
+%% function : install_event/X
+%% Arguments: - | Time (seconds)
+%% Returns : ok | EXIT | EXCEPTION
+%% Effect : Install necessary data in the IFR DB
+%%------------------------------------------------------------
+
+install_event() ->
+ install_event(0).
+
+install_event(Time) when is_integer(Time) ->
+ install_loop(?EVENT_IDL_MODULES, timer:seconds(Time));
+install_event(_Time) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%------------------------------------------------------------
+%% function : install_typed/X
+%% Arguments: - | Time (seconds)
+%% Returns : ok | EXIT | EXCEPTION
+%% Effect : Install necessary data in the IFR DB
+%%------------------------------------------------------------
+
+install_typed() ->
+ install_typed(0).
+
+install_typed(Time) when is_integer(Time) ->
+ install_loop(?TYPED_IDL_MODULES, timer:seconds(Time));
+install_typed(_Time) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+install_loop([], _) ->
+ ok;
+install_loop([H|T], Time) ->
+ H:'oe_register'(),
+ timer:sleep(Time),
+ install_loop(T, Time).
+
+%%------------------------------------------------------------
+%% function : uninstall/X
+%% Arguments: - | Time (seconds)
+%% Returns : ok | EXIT | EXCEPTION
+%% Effect : Remove data related to cosNotificationin from the IFR DB
+%%------------------------------------------------------------
+
+uninstall() ->
+ uninstall(0).
+
+uninstall(Time) when is_integer(Time) ->
+ uninstall_loop(lists:reverse(?IDL_MODULES), timer:seconds(Time));
+uninstall(_Time) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%------------------------------------------------------------
+%% function : uninstall_event/X
+%% Arguments: - | Time (seconds)
+%% Returns : ok | EXIT | EXCEPTION
+%% Effect : Remove data related to cosNotificationin from the IFR DB
+%%------------------------------------------------------------
+
+uninstall_event() ->
+ uninstall_event(0).
+
+uninstall_event(Time) when is_integer(Time) ->
+ uninstall_loop(lists:reverse(?EVENT_IDL_MODULES), timer:seconds(Time));
+uninstall_event(_Time) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%------------------------------------------------------------
+%% function : uninstall_typed/X
+%% Arguments: - | Time (seconds)
+%% Returns : ok | EXIT | EXCEPTION
+%% Effect : Remove data related to cosNotificationin from the IFR DB
+%%------------------------------------------------------------
+
+uninstall_typed() ->
+ uninstall_typed(0).
+
+uninstall_typed(Time) when is_integer(Time) ->
+ uninstall_loop(lists:reverse(?TYPED_IDL_MODULES), timer:seconds(Time));
+uninstall_typed(_Time) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+uninstall_loop([], _) ->
+ ok;
+uninstall_loop([H|T], Time) ->
+ H:'oe_unregister'(),
+ timer:sleep(Time),
+ uninstall_loop(T, Time).
+
+
+%%------------------------------------------------------------
+%% function : start/stop
+%% Arguments:
+%% Returns :
+%% Effect : Starts or stops the cosTRansaction application.
+%%------------------------------------------------------------
+
+start() ->
+ application:start(cosNotification).
+stop() ->
+ application:stop(cosNotification).
+
+%%------------------------------------------------------------
+%% function : start_factory
+%% Arguments: none or an argumentlist whith default values.
+%% Returns : ObjectRef | {'EXCEPTION', _} | {'EXIT', Reason}
+%% Effect : Starts a CosNotifyChannelAdmin_EventChannelFactory
+%%------------------------------------------------------------
+start_factory() ->
+ start_factory(?not_DEFAULT_SETTINGS).
+
+start_factory(Args) when is_list(Args) ->
+ SO = 'CosNotification_Common':get_option(server_options, Args, ?not_DEFAULT_SETTINGS),
+ SPEC = ['CosNotifyChannelAdmin_EventChannelFactory',Args,
+ [{sup_child, true},
+ {regname, {local, oe_cosNotificationFactory}}|SO]],
+ case supervisor:start_child(?SUPERVISOR_NAME, SPEC) of
+ {ok, Pid, Obj} when is_pid(Pid) ->
+ Obj;
+ Other->
+ orber:dbg("[~p] cosNotificationApp:start_factory( ~p ).~n"
+ "Reason: ~p~n", [?LINE, Args, Other], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+start_factory(Args) ->
+ orber:dbg("[~p] cosNotificationApp:start_factory( ~p ).~n"
+ "Bad parameters~n", [?LINE, Args], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%------------------------------------------------------------
+%% function : start_global_factory
+%% Arguments: none or an argumentlist whith default values.
+%% Returns : ObjectRef | {'EXCEPTION', _} | {'EXIT', Reason}
+%% Effect : Starts a CosNotifyChannelAdmin_EventChannelFactory
+%%------------------------------------------------------------
+start_global_factory() ->
+ start_global_factory(?not_DEFAULT_SETTINGS).
+
+start_global_factory(Args) when is_list(Args) ->
+ SO = 'CosNotification_Common':get_option(server_options, Args, ?not_DEFAULT_SETTINGS),
+ Name = create_name(),
+ SPEC = ['CosNotifyChannelAdmin_EventChannelFactory',Args,
+ [{sup_child, true},
+ {regname, {global, Name}}|SO]],
+ case supervisor:start_child(?SUPERVISOR_NAME, SPEC) of
+ {ok, Pid, Obj} when is_pid(Pid) ->
+ Obj;
+ Other->
+ orber:dbg("[~p] cosNotificationApp:start_global_factory( ~p ).~n"
+ "Reason: ~p~n", [?LINE, Args, Other], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+start_global_factory(Args) ->
+ orber:dbg("[~p] cosNotificationApp:start_global_factory( ~p ).~n"
+ "Bad parameters~n", [?LINE, Args], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+
+%%------------------------------------------------------------
+%% function : stop_factory
+%% Arguments: Factory Object Reference
+%% Returns : ok | {'EXCEPTION', _}
+%% Effect :
+%%------------------------------------------------------------
+
+stop_factory(Fac)->
+ corba:dispose(Fac).
+
+%%------------------------------------------------------------
+%% function : start_filter_factory
+%% Arguments: none or an argumentlist which by default is defined
+%% in CosNotification_Definitions.hrl, i.e., '?not_FILTERFAC_DEF'
+%% Returns : ObjectRef | {'EXCEPTION', _} | {'EXIT', Reason}
+%% Effect : Starts a CosNotifyChannelAdmin_EventChannelFactory
+%%------------------------------------------------------------
+start_filter_factory() ->
+ start_filter_factory([{typecheck, true},
+ {tty, false},
+ {logfile, false},
+ {server_options, []}]).
+start_filter_factory(Args) when is_list(Args) ->
+ SO = 'CosNotification_Common':get_option(server_options, Args,
+ ?not_DEFAULT_SETTINGS),
+ SPEC = ['CosNotifyFilter_FilterFactory',Args, [{sup_child, true}|SO]],
+ case supervisor:start_child(?SUPERVISOR_NAME, SPEC) of
+ {ok, Pid, Obj} when is_pid(Pid) ->
+ Obj;
+ Other->
+ orber:dbg("[~p] cosNotificationApp:start_filter_factory( ~p ).~n"
+ "Reason: ~p~n", [?LINE, Args, Other], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+start_filter_factory(Args) ->
+ orber:dbg("[~p] cosNotificationApp:start_filter_factory( ~p ).~n"
+ "Bad parameters~n", [?LINE, Args], ?DEBUG_LEVEL),
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+
+%%------------------------------------------------------------
+%% function : stop_filter_factory
+%% Arguments: FilterFactory Object Reference
+%% Returns : ok | {'EXCEPTION', _}
+%% Effect :
+%%------------------------------------------------------------
+
+stop_filter_factory(Fac)->
+ corba:dispose(Fac).
+
+
+%%------------------------------------------------------------
+%% function : create_structured_event
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+create_structured_event(StrD,StrT,StrE,PSeqV,PSeqF,AnyR)
+ when is_list(StrD) andalso is_list(StrT) andalso is_list(StrE)
+ andalso is_list(PSeqV) andalso is_list(PSeqF) andalso
+ is_record(AnyR, any) ->
+#'CosNotification_StructuredEvent'{header =
+ #'CosNotification_EventHeader'{fixed_header =
+ #'CosNotification_FixedEventHeader'{event_type =
+ #'CosNotification_EventType'{domain_name=StrD,
+ type_name=StrT},
+ event_name = StrE},
+ variable_header = PSeqV},
+ filterable_data = PSeqF,
+ remainder_of_body = AnyR};
+create_structured_event(_StrD,_StrT,_StrE,_PSeqV,_PSeqF,_AnyR) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+
+%%------------------------------------------------------------
+%% function : type_check
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+type_check() ->
+ case application:get_env(cosNotification, type_check) of
+ {ok, Boolean} when is_atom(Boolean) ->
+ Boolean;
+ _ ->
+ true
+ end.
+
+%%------------------------------------------------------------
+%% function : notify
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+notify() ->
+ case application:get_env(cosNotification, notify) of
+ {ok, Module} when is_atom(Module) ->
+ Module;
+ _ ->
+ false
+ end.
+
+%%------------------------------------------------------------
+%% function : max_events
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+max_events() ->
+ case application:get_env(cosNotification, max_events) of
+ {ok, Max} when is_integer(Max) ->
+ Max;
+ _ ->
+ 50
+ end.
+
+%%------------------------------------------------------------
+%% function : timeout_events
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+timeout_events() ->
+ case application:get_env(cosNotification, timeout_events) of
+ {ok, Max} when is_integer(Max) ->
+ Max;
+ _ ->
+ 3000000 %% 5 minutes
+ end.
+
+
+%%------------------------------------------------------------
+%% function : interval_events
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+interval_events() ->
+ case application:get_env(cosNotification, interval_events) of
+ {ok, Max} when is_integer(Max) ->
+ Max;
+ _ ->
+ 10000 %% 10 seconds
+ end.
+
+
+%%------------------------------------------------------------
+%% function : start
+%% Arguments: Type - see module application
+%% Arg - see module application
+%% Returns :
+%% Effect : Module callback for application
+%%------------------------------------------------------------
+
+start(_, _) ->
+ supervisor:start_link({local, ?SUPERVISOR_NAME}, cosNotificationApp, app_init).
+
+
+%%------------------------------------------------------------
+%% function : stop
+%% Arguments: Arg - see module application
+%% Returns :
+%% Effect : Module callback for application
+%%------------------------------------------------------------
+
+stop(_) ->
+ ok.
+
+%%------------------------------------------------------------
+%% function : init
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+
+%% Starting using create_factory/X
+init(own_init) ->
+ {ok,{{simple_one_for_one,50,10},
+ [{"oe_NotChild",
+ {'CosNotification_Common',create_link, []},
+ transient,100000,worker,
+ ['CosNotifyChannelAdmin_EventChannel',
+ 'CosNotifyChannelAdmin_EventChannel_impl']}]}};
+%% When starting as an application.
+init(app_init) ->
+ {ok,{{simple_one_for_one,50,10},
+ [{"oe_NotChild",
+ {'CosNotification_Common',create_link, []},
+ transient,100000,worker,
+ ['CosNotifyChannelAdmin_EventChannel',
+ 'CosNotifyChannelAdmin_EventChannel_impl']}]}}.
+
+
+
+%%------------------------------------------------------------
+%% function : create_name
+%% Arguments:
+%% Returns :
+%% Effect : Create a unique name to use when, for eaxmple, starting
+%% a new server.
+%%------------------------------------------------------------
+create_name() ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat(['oe_',node(),'_',MSec, '_', Sec, '_', USec]).
+
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/cosNotificationAppComm.idl b/lib/cosNotification/src/cosNotificationAppComm.idl
new file mode 100644
index 0000000000..09e0af2568
--- /dev/null
+++ b/lib/cosNotification/src/cosNotificationAppComm.idl
@@ -0,0 +1,17 @@
+#ifndef _OE_COSNOTIFICATIONCOMM_IDL_
+#define _OE_COSNOTIFICATIONCOMM_IDL_
+
+#include<CosNotification.idl>
+
+module oe_CosNotificationComm {
+
+ interface Event {
+
+ enum status {MATCH, MATCHED};
+ void callSeq(in CosNotification::EventBatch events, in status stat);
+ void callAny(in any event, in status stat);
+ };
+
+};
+#endif /* ifndef _OE_COSNOTIFICATIONCOMM_IDL_ */
+
diff --git a/lib/cosNotification/src/cosNotificationComm.cfg b/lib/cosNotification/src/cosNotificationComm.cfg
new file mode 100644
index 0000000000..89d207528d
--- /dev/null
+++ b/lib/cosNotification/src/cosNotificationComm.cfg
@@ -0,0 +1,3 @@
+{this, "oe_CosNotificationComm::Event"}.
+{from, "oe_CosNotificationComm::Event"}.
+{{handle_info, "oe_CosNotificationComm::Event"}, true}.
diff --git a/lib/cosNotification/src/cosNotification_Filter.erl b/lib/cosNotification/src/cosNotification_Filter.erl
new file mode 100644
index 0000000000..dd3b5beb93
--- /dev/null
+++ b/lib/cosNotification/src/cosNotification_Filter.erl
@@ -0,0 +1,964 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : cosNotification_Filter.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module(cosNotification_Filter).
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%% Internal Filter Functions
+-export([eval/1,
+ eval/2,
+ create_filter/1,
+ check_types/1,
+ match_types/3,
+ validate_types/1]).
+
+%%--------------- DEFINES ------------------------------------
+-define(EVENT_PATH, [{dotid,"header"}, {dotid,"fixed_header"},
+ {dotid,"event_name"}]).
+-define(DOMAIN_PATH, [{dotid,"header"}, {dotid,"fixed_header"},
+ {dotid,"event_type"}, {dotid,"domain_name"}]).
+-define(TYPE_PATH, [{dotid,"header"}, {dotid,"fixed_header"},
+ {dotid,"event_type"}, {dotid,"type_name"}]).
+-define(VARIABLE_PATH(I), [{dotid,"header"}, {dotid,"variable_header"}, {dotid,I}]).
+-define(FILTERABLE_PATH(I), [{dotid,"filterable_data"}, {dotid,I}]).
+
+
+%%------------------------------------------------------------
+%%--------------- FILTER FUNCTIONS ---------------------------
+%%------------------------------------------------------------
+%%------------------------------------------------------------
+%% function : create_filter/1
+%% Arguments: String - Filter grammar
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+create_filter(Str) ->
+ {ok, Tokens} = cosNotification_Scanner:scan(Str),
+ case cosNotification_Grammar:parse(Tokens) of
+ {ok, Filter} ->
+ {ok, Filter};
+ _->
+ corba:raise(#'CosNotifyFilter_InvalidConstraint'{constr = Str})
+ end.
+
+%%------------------------------------------------------------
+%% function : eval
+%% Arguments:
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+
+eval('$empty') -> true;
+eval(Tree) -> eval(Tree, []).
+
+
+%% Leaf expressions (literals and idents).
+eval('$empty', _) -> true;
+eval(Lit, _Env) when is_number(Lit) -> Lit;
+eval(Lit, _Env) when is_list(Lit) -> Lit; %list == string
+eval(Lit, _Env) when is_atom(Lit) -> Lit; %atom == bool
+eval({component, V}, []) ->
+ %% Cannot evaluate variables at this stage.
+ throw({error, {unbound_variable, V}});
+eval({component, V}, Env) ->
+ case catch lookup(V, Env, undefined) of
+ {ok, Val} ->
+ Val;
+ _X ->
+ {error, {unbound_variable, V}}
+ end;
+
+%% CORBA2.3-15/26 states:
+%% "The name parameters in tk_objref, tk_struct, tk_union, tk_enum, tk_alias,
+%% tk_value, tk_value_box, tk_abstract_interface, tk_native and tk_except TypeCodes
+%% and the member name parameters in tk_struct, tk_union, tk_enum, tk_value and
+%% tk_except TypeCodes are not specified by (or significant in) GIOP. Agents should
+%% not make assumptions about type equivalence based on these name values; only the
+%% structural information (including RepositoryId values, if provided) is
+%% significant. If provided, the strings should be the simple, unscoped names
+%% supplied in the OMG IDL definition text. If omitted, they are encoded as empty
+%% strings."
+%% Makes it rather hard to follow the grammar 100 %.
+eval({default_component, V}, Env) ->
+ case catch lookup(V, Env, default_component) of
+ {ok, false} ->
+ false;
+ {ok, true} ->
+ true;
+ _X ->
+ {error, {unbound_variable, V}}
+ end;
+eval({exist_component, V}, Env) ->
+ case catch lookup(V, Env, exist_component) of
+ {ok, false} ->
+ false;
+ {ok, _} ->
+ true;
+ {error, _} ->
+ false;
+ _X ->
+ {error, {unbound_variable, V}}
+ end;
+%% Arithmetic expressions.
+eval({'*', X, Y}, Env) ->
+ eval_arith({fun(_X, _Y) -> _X*_Y end, X, Y}, Env);
+eval({'/', X, Y}, Env) ->
+ eval_arith({fun(_X, _Y) -> _X/_Y end, X, Y}, Env);
+eval({'+', X, Y}, Env) ->
+ eval_arith({fun(_X, _Y) -> _X+_Y end, X, Y}, Env);
+eval({'-', X, Y}, Env) ->
+ eval_arith({fun(_X, _Y) -> _X-_Y end, X, Y}, Env);
+eval({'u-', X}, Env) ->
+ eval_arith({fun(_X) -> -_X end, X}, Env);
+%% Relational expressions.
+eval({'==', X, Y}, Env) ->
+ eval_rel({fun(_X, _Y) -> _X == _Y end, X, Y}, Env);
+eval({'!=', X, Y}, Env) ->
+ eval_rel({fun(_X, _Y) -> _X /= _Y end, X, Y}, Env);
+eval({'<', X, Y}, Env) ->
+ eval_rel({fun(_X, _Y) -> _X < _Y end, X, Y}, Env);
+eval({'<=', X, Y}, Env) ->
+ eval_rel({fun(_X, _Y) -> _X =< _Y end, X, Y}, Env);
+eval({'>', X, Y}, Env) ->
+ eval_rel({fun(_X, _Y) -> _X > _Y end, X, Y}, Env);
+eval({'>=', X, Y}, Env) ->
+ eval_rel({fun(_X, _Y) -> _X >= _Y end, X, Y}, Env);
+eval({'~', Needle, Haystack}, Env) -> %substring match
+ N = eval(Needle, Env),
+ H = eval(Haystack, Env),
+ if
+ is_list(N) andalso is_list(H) ->
+ string:str(H, N) /= 0;
+ true ->
+ throw({error, {bad_type, Needle, Haystack}})
+ end;
+eval({'in', Needle, Haystack}, Env) -> %set membership
+ N = eval(Needle, Env),
+ H = eval(Haystack, Env),
+ if
+ is_list(H) ->
+ lists:member(N, H);
+ true ->
+ throw({error, {bad_type, Needle, Haystack}})
+ end;
+%% Boolean expressions.
+eval({'and', false, _Y}, _Env) ->
+ false;
+eval({'and', _X, false}, _Env) ->
+ false;
+eval({'and', X, Y}, Env) ->
+ eval_and_bool({fun(_X, _Y) -> _X and _Y end, X, Y}, Env);
+
+eval({'or', true, _Y}, _Env) ->
+ true;
+eval({'or', _X, true}, _Env) ->
+ true;
+eval({'or', X, Y}, Env) ->
+ eval_or_bool({fun(_X, _Y) -> _X or _Y end, X, Y}, Env);
+eval({'not', X}, Env) ->
+ eval_bool({fun(_X) -> not _X end, X}, Env);
+%% Catch-all
+eval(_T, _Env) ->
+ throw({error, internal}).
+
+eval_bool({Fun, X}, Env) ->
+ Xe = eval(X, Env),
+ if
+ is_atom(Xe) ->
+ Fun(Xe);
+ true ->
+ throw({error, {bad_type, X}})
+ end.
+eval_and_bool({Fun, X, Y}, Env) ->
+ case eval(X, Env) of
+ false ->
+ %% No need for evaluating the other expression.
+ false;
+ Xe ->
+ Ye = eval(Y, Env),
+ if
+ is_atom(Xe) andalso is_atom(Ye) ->
+ Fun(Xe, Ye);
+ true ->
+ throw({error, {bad_type, X, Y}})
+ end
+ end.
+eval_or_bool({Fun, X, Y}, Env) ->
+ case eval(X, Env) of
+ true ->
+ %% No need for evaluating the other expression.
+ true;
+ Xe ->
+ Ye = eval(Y, Env),
+ if
+ is_atom(Xe) andalso is_atom(Ye) ->
+ Fun(Xe, Ye);
+ true ->
+ throw({error, {bad_type, X, Y}})
+ end
+ end.
+
+
+%% According to issue 2203, OMG stated that arithmetic operations involving booleans
+%% is allowed. TRUE equals 1 and FALSE 0. They refer to:
+
+%% "We at NEC like this feature, and feel it is both required and
+%% standard with the way CORBA treats boolean values. We feel it's
+%% required because it allows the constraint grammar to handle
+%% expressions that combine the results of boolean comparisons,
+%% which we feel is typically expected of a constraint grammar
+%% (e.g., ($.fruit == apples) + ($.color == red) + ($.kind == macintosh) > 2)
+%% Furthermore, while we have no fundamental opposition to explicitly
+%% stating that TRUE=1 and FALSE=0, we don't necessarily feel it's
+%% necessary because section 12.3.1 of CORBA alread states that
+%% "Boolean values are encoded as single octets, where TRUE is the
+%% value 1, and FALSE is 0." Essentially, we feel CORBA already
+%% defines TRUE to be 1 and FALSE to be 0, however we are not
+%% opposed to adding such a statement into Notification if folks
+%% feel it's necessary."
+%% If still valid, see: ftp://ftp.omg.org/pub/docs/telecom/99-07-06.txt
+
+%% The section they refer to (CORBA-2.0) merely states that TRUE and FALSE are
+%% encoded as 1 and 0 in GIOP. Does not imply that booleans may be used as numeric.
+%% But, they have stated that this should be the case so.....
+
+remap_bool(Num) when is_number(Num) -> Num;
+remap_bool(true) -> 1;
+remap_bool(false) -> 0;
+remap_bool(X) -> throw({error, {bad_type, X}}).
+
+eval_arith({Fun, X}, Env) ->
+ Xe = remap_bool(eval(X, Env)),
+ Fun(Xe);
+eval_arith({Fun, X, Y}, Env) ->
+ Xe = remap_bool(eval(X, Env)),
+ Ye = remap_bool(eval(Y, Env)),
+ Fun(Xe, Ye).
+
+eval_rel({Fun, X, Y}, Env) ->
+ Xe = eval(X, Env),
+ Ye = eval(Y, Env),
+ if
+ is_number(Xe) andalso is_number(Ye) ->
+ Fun(Xe, Ye);
+ is_list(Xe) andalso is_list(Ye) ->
+ Fun(Xe, Ye);
+ is_atom(Xe) andalso is_atom(Ye) ->
+ Fun(Xe, Ye);
+ true ->
+ throw({error, {bad_type, X, Y}})
+ end.
+
+%%------------------------------------------------------------
+%% function : get_variable
+%% Arguments: A sequence of CosNotification::Property{}, i.e.,
+%% name-value pairs.
+%% ID - name in the Property
+%% Any - remainder of body
+%% Returns : Value in the Property | false
+%% Comment : When searching for a variable we must start with
+%% 'variable_header' followed by 'filterable_body'.
+%% If not found we will then look in the 'remainder_of_body'
+%%------------------------------------------------------------
+
+get_variable([], ID, Any) when is_record(Any, any) ->
+ case {any:get_value(Any), any:get_typecode(Any)} of
+ {#'CosNotification_Property'{name=ID, value=A}, _} ->
+ any:get_value(A);
+ {_, TC} when is_atom(TC) ->
+ %% Since TC atom it must be a simple type, which don't have members.
+ throw({error, {bad_id, ID}});
+ {Value, {tk_alias,_,ID,_}} when is_record(Value, any) ->
+ %% {tk_alias, IFRId, ID, TypeCode}
+ any:get_value(Value);
+ {Value, {tk_alias,_,ID,_}} ->
+ %% {tk_alias, IFRId, ID, TypeCode}
+ Value;
+ {Value, _TC} ->
+ get_variable([],ID, Value)
+ end;
+get_variable([], ID, #'CosNotification_Property'{name=ID, value=Any}) ->
+ any:get_value(Any);
+get_variable([], ID, [#'CosNotification_Property'{name=ID, value=Any}|_]) ->
+ any:get_value(Any);
+get_variable([], ID, [H|T]) when is_record(H, 'CosNotification_Property') ->
+ get_variable([], ID, T);
+get_variable([], ID, false) ->
+ throw({error, {bad_id, ID}});
+get_variable([], ID, Value) ->
+ M = element(1, Value),
+ case catch M:tc() of
+ {tk_struct,_,_,SList} ->
+ %% {tk_struct, Id, Name, ElementList}.
+ Field = get_field(ID, SList),
+ element(Field, Value);
+ {tk_union,_,_,_, DefNo, UList} ->
+ %% {tk_union, Id, Name, DiscrTC, Default, ElementList}
+ case id2switch(UList, ID) of
+ [default] when DefNo >= 0 ->
+ element(3, Value);
+ [default] ->
+ throw({error, {bad_id, "Bad Union ID supplied"}});
+ Found ->
+ case catch lists:member(element(2, Value), Found) of
+ true ->
+ element(3, Value);
+ _ ->
+ throw({error, {bad_id, "Bad Union ID supplied"}})
+ end
+ end;
+ _->
+ throw({error, {bad_id, ID}})
+ end;
+get_variable([#'CosNotification_Property'{name=ID, value=A}|_], ID, _) ->
+ any:get_value(A);
+get_variable([_|T], ID, Any) ->
+ get_variable(T, ID, Any).
+
+%%------------------------------------------------------------
+%% function : lookup
+%% Arguments: T - A parse tree representing the grammar.
+%% S - The event we want to extract data from
+%% Op - which type of lookup should be done on this
+%% component, e.g., 'default' or 'exist'.
+%% Returns : {ok, boolean()} |
+%% {error, _}
+%% Comment : WARNING!!!!
+%% This function uses some Orber core information to
+%% extract data, e.g., TypeCode representation. Why?
+%% We don't want to see the performance take a plunge
+%% due to that users write constraints which they
+%% can/may not know is slow. The alternative would be
+%% to use the IFR. However, these shortcuts aren't
+%% that frequent and we can easily update the code.
+%% To update, investigate:
+%% * lookup/3 cases related to '_type_id'
+%% * lookup/3 cases related to unions
+%% * get_variable/3
+%% * id2switch/2
+%% * switch2alias/2
+%%------------------------------------------------------------
+%% Done parsing, return the result.
+lookup([],S,_) -> {ok, S};
+lookup('$empty', #'CosNotification_StructuredEvent'{remainder_of_body = Any},_) ->
+ {ok, any:get_value(Any)};
+lookup('$empty',S,_) when is_record(S, any) ->
+ {ok, any:get_value(S)};
+
+%%------- varid --------
+%% CosNotification-revision-98-11-01/46 states:
+%% "The following rules govern translation of a run-time variable, $variable ,
+%% into a specific event field. If the run-time variable is reserved
+%% (e.g., $curtime) this translation takes precedence. Next, the first matching
+%% translation is chosen respectively from:
+%% * a simple-typed member of $.header.fixed_header,
+%% * properties in $.header.variable_header,
+%% and properties in $.header.filterable_data.
+%% If no match is found, the translation defaults to $.variable.
+%% Given these rules, an unstructured event with a $.priority member and a
+%% structured event using $.header.variable_header(priority) can be specified
+%% in a generic constraint using the run-time variable $priority .
+%% Alternatively, a constraint can be written specifically for a structured or
+%% unstructured event by avoiding the use of run-time variables."
+
+%% The above contains one error; $.header.filterable_data is not a part of the
+%% header, but contained in the event body.
+
+%% For any events we must first verify that a path exist, e.g.,
+%% "header"->"fixed_header"->"event_type"->"domain_name", otherwise we will
+%% use {dotid, "xxx"}.
+lookup([{varid, "type_name"}|T],
+ #'CosNotification_StructuredEvent'
+ {header = #'CosNotification_EventHeader'
+ {fixed_header = #'CosNotification_FixedEventHeader'
+ {event_type = #'CosNotification_EventType'{type_name=TN}}}}, Op) ->
+ lookup(T, TN, Op);
+lookup([{varid, "type_name"}|T], Any, Op) when is_record(Any, any) ->
+ case locate_var([?TYPE_PATH, ?VARIABLE_PATH("type_name"),
+ ?FILTERABLE_PATH("type_name")], Any, Op) of
+ {ok, Val} ->
+ lookup(T, Val, Op);
+ _ ->
+ lookup(T, get_variable([], "type_name", Any), Op)
+ end;
+lookup([{varid, "domain_name"}|T],
+ #'CosNotification_StructuredEvent'
+ {header = #'CosNotification_EventHeader'
+ {fixed_header = #'CosNotification_FixedEventHeader'
+ {event_type = #'CosNotification_EventType'{domain_name=DN}}}}, Op) ->
+ lookup(T, DN, Op);
+lookup([{varid, "domain_name"}|T], Any, Op) when is_record(Any, any) ->
+ case locate_var([?DOMAIN_PATH, ?VARIABLE_PATH("domain_name"),
+ ?FILTERABLE_PATH("domain_name")], Any, Op) of
+ {ok, Val} ->
+ lookup(T, Val, Op);
+ _ ->
+ lookup(T, get_variable([], "domain_name", Any), Op)
+ end;
+lookup([{varid, "event_name"}|T],
+ #'CosNotification_StructuredEvent'
+ {header = #'CosNotification_EventHeader'
+ {fixed_header = #'CosNotification_FixedEventHeader'
+ {event_name = EN}}}, Op) ->
+ lookup(T, EN, Op);
+lookup([{varid, "event_name"}|T], Any, Op) when is_record(Any, any) ->
+ case locate_var([?EVENT_PATH, ?VARIABLE_PATH("event_name"),
+ ?FILTERABLE_PATH("event_name")], Any, Op) of
+ {ok, Val} ->
+ lookup(T, Val, Op);
+ _ ->
+ lookup(T, get_variable([], "event_name", Any), Op)
+ end;
+
+lookup([{varid, ID}|T],
+ #'CosNotification_StructuredEvent'{header =
+ #'CosNotification_EventHeader'{variable_header = VS},
+ filterable_data = FS,
+ remainder_of_body = Any}, Op) ->
+ lookup(T, get_variable(VS++FS, ID, Any), Op);
+lookup([{varid, ID}|T], Any, Op) ->
+ case locate_var([?VARIABLE_PATH(ID), ?FILTERABLE_PATH(ID)], Any, Op) of
+ {ok, Val} ->
+ lookup(T, Val, Op);
+ _ ->
+ lookup(T, get_variable([], ID, Any), Op)
+ end;
+
+%%------- dotid --------
+%% First level
+lookup([{dotid, "header"}|T],
+ #'CosNotification_StructuredEvent'{header = S}, Op) ->
+ lookup(T, S, Op);
+lookup([{dotid, "filterable_data"}|T],
+ #'CosNotification_StructuredEvent'{filterable_data = S}, Op) ->
+ lookup(T, S, Op);
+
+lookup([{dotid, remainder_of_body}|T],
+ #'CosNotification_StructuredEvent'{remainder_of_body = S}, Op) ->
+ lookup(T, S, Op);
+%% Second level. Previous token must have been header
+lookup([{dotid, "fixed_header"}|T],
+ #'CosNotification_EventHeader'{fixed_header = S}, Op) ->
+ lookup(T, S, Op);
+lookup([{dotid, "variable_header"}|T],
+ #'CosNotification_EventHeader'{variable_header = S}, Op) ->
+ lookup(T, S, Op);
+%% Third level. Previous token must have been fixed_header.
+lookup([{dotid, "event_type"}|T],
+ #'CosNotification_FixedEventHeader'{event_type = S}, Op) ->
+ lookup(T, S, Op);
+lookup([{dotid, "event_name"}|T],
+ #'CosNotification_FixedEventHeader'{event_name = S}, Op) ->
+ lookup(T, S, Op);
+%% Fourth level. Previous token must have been event_type
+lookup([{dotid, "domain_name"}|T], #'CosNotification_EventType'{domain_name = S}, Op) ->
+ lookup(T, S, Op);
+lookup([{dotid, "type_name"}|T], #'CosNotification_EventType'{type_name = S}, Op) ->
+ lookup(T, S, Op);
+
+%% Leaf expressions
+lookup([{dotid, "name"}|T], #'CosNotification_Property'{name=S}, Op) ->
+ lookup(T, S, Op);
+lookup([{dotid, "value"}|T], #'CosNotification_Property'{value=S}, Op) ->
+ lookup(T, S, Op);
+
+lookup([{dotid, ID}|T],
+ #'CosNotification_StructuredEvent'{remainder_of_body = Any}, Op) ->
+ lookup(T, get_variable([], ID, Any), Op);
+lookup([{dotid, ID}|T], Any, Op) ->
+ lookup(T, get_variable([], ID, Any), Op);
+
+lookup([{associd, ID}|T], S, Op) when is_list(S) ->
+ %% Refers to an associative array, i.e., a list of
+ %% #'CosNotification_Property'{name=ID, value=A}
+ lookup(T, get_variable(S, ID, false), Op);
+
+lookup([{dotint, Position}|T], S, Op) when is_record(S, any) ->
+ lookup(T, element(Position+2, any:get_value(S)), Op);
+lookup([{dotint, Position}|T], S, Op) ->
+ lookup(T, element(Position+2, S), Op);
+
+lookup([{uint, ID}|T], S, Op) when is_record(S, any) ->
+ lookup([{uint, ID}|T], any:get_value(S), Op);
+lookup([{uint, ID} |T], S, Op) when is_tuple(S) ->
+ case catch element(2, S) of
+ ID ->
+ %% The supplied union do contain the requested discriminator.
+ lookup(T, element(3, S), Op);
+ _Other when Op == exist_component ->
+ throw({error, {bad_id, "Bad Union ID"}});
+ Other ->
+ %% Check if default is allowed.
+ M = element(1, S),
+ case catch M:tc() of
+ {tk_union,_,_,_,DefNo, UList} ->
+ %% {tk_union, Id, Name, DiscrTC, Default, ElementList}
+ case switch2alias(UList, ID) of
+ {ok, [], _} ->
+ throw({error, {bad_id, "Bad Union ID"}});
+ {ok, default, _} when DefNo >= 0 ->
+ lookup(T, element(3, S), Op);
+ {ok, List, _} ->
+ case lists:member(Other, List) of
+ true ->
+ lookup(T, element(3, S), Op);
+ _->
+ throw({error, {bad_id, "Bad Union ID"}})
+ end
+ end
+ end
+ end;
+lookup([{ustr, ID}|T], S, Op) when is_record(S, any) ->
+ lookup([{ustr, ID}|T], any:get_value(S), Op);
+lookup([{ustr, ID}|T], S, Op) when is_tuple(S) ->
+ M = element(1, S),
+ case catch M:tc() of
+ {tk_union,_,_,_,DefNo, UList} ->
+ case id2switch(UList, ID) of
+ [default] when DefNo >= 0 ->
+ lookup(T, element(3, S), Op);
+ [default] ->
+ throw({error, {bad_id, "Bad Union ID supplied"}});
+ Found ->
+ case catch lists:member(element(2, S), Found) of
+ true ->
+ lookup(T, element(3, S), Op);
+ _ ->
+ throw({error, {bad_id, "Bad Union ID supplied"}})
+ end
+ end
+ end;
+lookup([default|T], S, Op) when is_record(S, any) ->
+ lookup([default|T], any:get_value(S), Op);
+lookup([default|T], S, Op) when is_tuple(S) ->
+ M = element(1, S),
+ case catch M:tc() of
+ {tk_union,_,_,_,DefNo, _UList} when DefNo < 0 ->
+ %% {tk_union, Id, Name, DiscrTC, Default, ElementList}
+ throw({error, {bad_id, "No default discriminator"}});
+ {tk_union,_,_,_,_DefNo, UList} ->
+ %% {tk_union, Id, Name, DiscrTC, Default, ElementList}
+ %% Check if the label really is default.
+ case lists:keymember(element(2, S), 1, UList) of
+ false ->
+ lookup(T, element(3, S), Op);
+ _->
+ throw({error, {bad_id, "Bad Union"}})
+ end;
+ _->
+ throw({error, {bad_id, "Bad Union"}})
+ end;
+
+lookup([{arrindex, Index}|T], S, Op) when is_tuple(S) ->
+ %% The OMG uses c/c++ index. We must add one.
+ lookup(T, element(Index+1,S), Op);
+
+%%%%%%%%%%%%%%%%%%%%%%% LEAF EXPRESSIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% got '$._length', which maps to the 'remainder_of_body'
+lookup(['_length'],
+ #'CosNotification_StructuredEvent'{remainder_of_body = Any}, _Op) ->
+ {ok, length(any:get_value(Any))};
+lookup(['_length'], S, _Op) when is_record(S, any) ->
+ {ok, length(any:get_value(S))};
+lookup(['_length'], S, _Op) when is_list(S) ->
+ {ok, length(S)};
+lookup(['_length'], S, _Op) when is_tuple(S) ->
+ {ok, length(tuple_to_list(S))};
+
+%% got '$._d', which maps to the 'remainder_of_body'
+%% The discriminator may, accordiong to the CORBA specification, be (2.3/p3-37):
+%% * integer_type
+%% * char_type
+%% * boolean_type
+%% * enum_type
+%% * scoped_name
+lookup(['_d'],
+ #'CosNotification_StructuredEvent'{remainder_of_body = Any},
+ default_component) ->
+ lookup(['_d'], any:get_value(Any), default_component);
+lookup(['_d'], S, default_component) when is_record(S, any) ->
+ lookup(['_d'], any:get_value(S), default_component);
+lookup(['_d'], S, default_component) ->
+ M = element(1, S),
+ case catch M:tc() of
+ {tk_union,_,_,_,DefNo,_} when DefNo < 0 ->
+ %% '-1' indicates that no default value may exist.
+ {ok, false};
+ {tk_union,_,_,_,_,UList} ->
+ %% May be using the default setting; check if the Value is in the list.
+ {ok, not lists:keymember(element(2, S), 1, UList)};
+ _ ->
+ {ok, false}
+ end;
+lookup(['_d'],
+ #'CosNotification_StructuredEvent'{remainder_of_body = Any}, _Op) ->
+ {ok, element(2, any:get_value(Any))};
+lookup(['_d'], S, _Op) when is_record(S, any) ->
+ {ok, element(2, any:get_value(S))};
+lookup(['_d'], S, _Op) ->
+ {ok, element(2, S)};
+
+
+lookup(['_type_id'], S, _Op) when is_record(S,'CosNotification_StructuredEvent') ->
+ {ok, "StructuredEvent"};
+lookup(['_type_id'], S, _Op) when is_record(S,'CosNotification_EventHeader') ->
+ {ok, "EventHeader"};
+lookup(['_type_id'], S, _Op) when is_record(S,'CosNotification_FixedEventHeader') ->
+ {ok, "FixedEventHeader"};
+lookup(['_type_id'], S, _Op) when is_record(S,'CosNotification_EventType') ->
+ {ok, "EventType"};
+lookup(['_type_id'], S, _Op) when is_record(S,'CosNotification_Property') ->
+ {ok, "Property"};
+lookup(['_type_id'], S, _Op) when is_tuple(S) ->
+ M=element(1, S),
+ Name = case catch M:tc() of
+ {tk_union,_,ID,_,_,_} ->
+ ID;
+ {tk_enum, _, ID, _} ->
+ ID;
+ {tk_exception, _, ID, _} ->
+ ID;
+ {tk_alias, _, ID, _} ->
+ ID;
+ {tk_struct,_,ID,_} ->
+ ID
+ end,
+ {ok, Name};
+
+lookup(['_repos_id'], S, _Op) when is_record(S,'CosNotification_StructuredEvent') ->
+ {ok, 'CosNotification_StructuredEvent':id()};
+lookup(['_repos_id'], S, _Op) when is_record(S,'CosNotification_EventHeader') ->
+ {ok, 'CosNotification_EventHeader':id()};
+lookup(['_repos_id'], S, _Op) when is_record(S,'CosNotification_FixedEventHeader') ->
+ {ok, 'CosNotification_FixedEventHeader':id()};
+lookup(['_repos_id'], S, _Op) when is_record(S,'CosNotification_EventType') ->
+ {ok, 'CosNotification_EventType':id()};
+lookup(['_repos_id'], S, _Op) when is_record(S,'CosNotification_Property') ->
+ {ok, 'CosNotification_Property':id()};
+lookup(['_repos_id'], S, _Op) when is_tuple(S) ->
+ M = element(1, S),
+ {ok, M:id()};
+
+lookup(_, _, _) ->
+ error.
+
+
+%%------------------------------------------------------------
+%% function : locate_var
+%% Arguments: Paths - A list of path-lists which tells us where
+%% to search for runtime variables and in which
+%% order.
+%% S - Data
+%% Op - se lookup/3
+%% Returns : {error, _} |
+%% {ok, Val}
+%%------------------------------------------------------------
+locate_var([], _S, _) ->
+ {error, "not found"};
+locate_var([H|T], S, Op) ->
+ case catch lookup(H, S, Op) of
+ {ok, Val} ->
+ {ok,Val};
+ _ ->
+ locate_var(T, S, Op)
+ end.
+
+%%------------------------------------------------------------
+%% function : id2switch
+%% Arguments: UList - The list of elements contained in the
+%% Union TypeCode.
+%% ID - string() eq name of element.
+%% Returns : Acc - A list of switches related to given ID.
+%%------------------------------------------------------------
+id2switch(UList, ID) ->
+ id2switch(UList, ID, [], false).
+id2switch([], _, Acc, _) ->
+ Acc;
+id2switch([{Sw, ID, _}|T], ID, Acc, _) ->
+ id2switch(T, ID, [Sw|Acc], true);
+id2switch([_|_T], _ID, Acc, true) ->
+ Acc;
+id2switch([_|T], ID, Acc, Found) ->
+ id2switch(T, ID, Acc, Found).
+
+%%------------------------------------------------------------
+%% function : switch2alias
+%% Arguments: UList - The list of elements contained in the
+%% Union TypeCode.
+%% Switch - the union discriminator.
+%% Returns : Acc - A list of switches that are defined with the same
+%% ID - The switches common ID.
+%% Comment : A union IDL code can look like:
+%% union Union switch(long) {
+%% case 1:
+%% case 2: long ID; };
+%% In this case supplying Switch == 1 (or) the result
+%% should be {ok, [1,2], "ID"}
+%%------------------------------------------------------------
+switch2alias([], _Switch) ->
+ %% Is it really possible to define an empty union??
+ {ok, [], undefined};
+switch2alias([{Sw, ID, TC}|UList], Switch) ->
+ switch2alias([{Sw, ID, TC}|UList], Switch, [], ID, false).
+
+
+switch2alias([{default, ID, _}], _, _, _, false) ->
+ {ok, default, ID};
+switch2alias([], _, _Acc, _, false) ->
+ {ok, [], undefined};
+switch2alias([], _, Acc, PreviousID, _) ->
+ {ok, Acc, PreviousID};
+
+%% Seen the ID before but just found the correct switch, e.g.,
+%% [... {0,"K",{tk_string,0}}, {2,"K",{tk_string,0}}...] and switch eq '2'
+switch2alias([{Switch, PreviousID, _}|T], Switch, Acc, PreviousID, _Found) ->
+ switch2alias(T, Switch, [Switch|Acc], PreviousID, true);
+
+%% First time for this ID and found the correct switch
+switch2alias([{Switch, ID, _}|T], Switch, _Acc, _PreviousID, false) ->
+ switch2alias(T, Switch, [Switch], ID, true);
+
+%% Seen this ID and found the correct switch before.
+switch2alias([{Sw, PreviousID, _}|T], Switch, Acc, PreviousID, true) ->
+ switch2alias(T, Switch, [Sw|Acc], PreviousID, true);
+
+%% Seen this ID but not found the correct switch.
+switch2alias([{Sw, PreviousID, _}|T], Switch, Acc, PreviousID, false) ->
+ switch2alias(T, Switch, [Sw|Acc], PreviousID, false);
+
+%% No more of the correct ID/Switch. Done.
+switch2alias([{_, _ID, _}|_], _, Acc, PreviousID, true) ->
+ {ok, Acc, PreviousID};
+%% Not found correct switch and ID is updated.
+switch2alias([{Sw, ID, _}|T], Switch, _Acc, _PreviousID, Found) ->
+ switch2alias(T, Switch, [Sw], ID, Found).
+
+
+%%------------------------------------------------------------
+%% function : get_field
+%% Arguments: ID - element name
+%% List - The list of elements contained in the
+%% TypeCode.
+%% Returns : false |
+%% offset
+%%------------------------------------------------------------
+get_field(ID, List) ->
+ get_field(ID, List, 2).
+get_field(_ID, [], _) ->
+ false;
+get_field(ID, [ID|_], I) ->
+ %% Memberlists in enum.
+ I;
+get_field(ID, [{ID,_}|_], I) ->
+ %% Memberlists in structs.
+ I;
+get_field(ID, [_|T], I) ->
+ get_field(ID, T, I+1).
+
+%%------------------------------------------------------------
+%% function : check_types
+%% Arguments: A sequence of CosNotification::EventType{}, i.e.,
+%% name-value pairs.
+%% Returns : {ok, WhichType, WC}
+%% WhichType - type/domain/both
+%% WC - [Types using wildcard]
+%%------------------------------------------------------------
+%% With check_types we try to determin if one or more EventTypes force us to check
+%% all events against this constraint. For example:
+%% EventType A1 has domain_name="car",type_name = "*"
+%% EventType A2 has domain_name="*",type_name = "DodgeViper"
+%% Since A1 says that we must test against any type_name and A2
+%% against any domain_name, we must test all events using these permutations.
+%% It's better to do these test now instead of when we are up and running. But
+%% if a client change the constraints VERY often it's up to them and they have
+%% to accept the delay.
+%%------------------------------------------------------------
+
+%% If types is an empty list it means that this constraint must be used
+%% for all events.
+check_types([]) -> true;
+check_types(Types) -> check_types(Types, both, []).
+check_types([], Which, WildCard) -> {ok, Which, WildCard};
+%% The following cases means that all events matches.
+check_types([#'CosNotification_EventType'{domain_name="",type_name = ""}|_T],_,_) ->
+ true;
+check_types([#'CosNotification_EventType'{domain_name="",type_name = "*"}|_T],_,_) ->
+ true;
+check_types([#'CosNotification_EventType'{domain_name="*",type_name = ""}|_T],_,_) ->
+ true;
+check_types([#'CosNotification_EventType'{domain_name="*",type_name = "*"}|_T],_,_) ->
+ true;
+%% The following cases means that all events must be tested using this constraint.
+check_types([#'CosNotification_EventType'{domain_name="",type_name = Ty}|T], domain,WC) when is_list(Ty) ->
+ check_wildcard(T, all, WC, "", Ty);
+check_types([#'CosNotification_EventType'{domain_name="*",type_name = Ty}|T], domain, WC) when is_list(Ty) ->
+ check_wildcard(T, all, WC, "", Ty);
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name = ""}|T], type,WC) when is_list(Do) ->
+ check_wildcard(T, all, WC, Do, "");
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name = "*"}|T], type,WC) when is_list(Do) ->
+ check_wildcard(T, all, WC, Do, "");
+%% The following cases is used to prevent other cases from converting,
+%% for example, all->type.
+check_types([#'CosNotification_EventType'{domain_name="",type_name = Ty}|T], all,WC) when is_list(Ty) ->
+ check_wildcard(T, all, WC, "", Ty);
+check_types([#'CosNotification_EventType'{domain_name="*",type_name = Ty}|T], all,WC) when is_list(Ty) ->
+ check_wildcard(T, all, WC, "", Ty);
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name = ""}|T], all,WC) when is_list(Do) ->
+ check_wildcard(T, all, WC, Do, "");
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name = "*"}|T], all,WC) when is_list(Do) ->
+ check_wildcard(T, all, WC, Do, "");
+%% The following cases means that all events with matching Type must be
+%% tested using this constraint.
+check_types([#'CosNotification_EventType'{domain_name="",type_name = Ty}|T], _W,WC) when is_list(Ty) ->
+ check_wildcard(T, type, WC, "", Ty);
+check_types([#'CosNotification_EventType'{domain_name="*",type_name = Ty}|T], _W,WC) when is_list(Ty) ->
+ check_wildcard(T, type, WC, "", Ty);
+%% The following cases means that all events with matching Domain must be
+%% tested using this constraint.
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name = ""}|T], _W,WC) when is_list(Do) ->
+ check_wildcard(T, domain, WC, Do, "");
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name = "*"}|T], _W,WC) when is_list(Do) ->
+ check_wildcard(T, domain, WC, Do, "");
+%% Sorry, no shortcuts.
+check_types([#'CosNotification_EventType'{domain_name=Do,type_name=Ty}|T], W,WC) when is_list(Do) andalso is_list(Ty) ->
+ check_wildcard(T, W, WC, Do, Ty);
+check_types([H|_], _,_) when is_record(H, 'CosNotification_EventType') ->
+ %% Not valid.
+ corba:raise(#'CosNotifyComm_InvalidEventType'{type=H});
+check_types(_,_,_) ->
+ %% Wasn't even a correct input.
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+check_wildcard(Types, Which, WC, Domain, Type) ->
+ NewWC =
+ case {string:chr(Domain, $*), string:chr(Type, $*)} of
+ {0, 0} ->
+ WC;
+ {0, _}->
+ [{type, Domain, convert_wildcard(Type, [])}|WC];
+ {_, 0}->
+ [{domain, convert_wildcard(Domain, []), Type}|WC];
+ _->
+ [{both, convert_wildcard(Domain, []), convert_wildcard(Type, [])}|WC]
+ end,
+ check_types(Types, Which, NewWC).
+
+%% Change '*' to '.*', see regexp:parse/2 documentation.
+convert_wildcard([], Acc) ->
+ case regexp:parse(lists:reverse(Acc)) of
+ {ok, Expr} ->
+ Expr;
+ _ ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO})
+ end;
+convert_wildcard([$*|T], Acc) ->
+ convert_wildcard(T, [$*, $.|Acc]);
+convert_wildcard([H|T], Acc) ->
+ convert_wildcard(T, [H|Acc]).
+
+%%------------------------------------------------------------
+%% function : match_types
+%% Arguments: A sequence of {Which, Domain, Type}, i.e., the same as
+%% returned from cosNotification_Filter:check_types/3
+%% Returns : bolean()
+%%------------------------------------------------------------
+match_types(_, _, []) ->
+ false;
+match_types(Domain, Type, [{domain, WCDomain, Type}|T]) ->
+ L=length(Domain),
+ case catch regexp:matches(Domain, WCDomain) of
+ {match, []} ->
+ match_types(Domain, Type, T);
+ {match, [{1, L}]} ->
+ true;
+ _->
+ match_types(Domain, Type, T)
+ end;
+match_types(Domain, Type, [{type, Domain, WCType}|T]) ->
+ L=length(Type),
+ case catch regexp:matches(Type, WCType) of
+ {match, []} ->
+ match_types(Domain, Type, T);
+ {match, [{1, L}]} ->
+ true;
+ _->
+ match_types(Domain, Type, T)
+ end;
+match_types(Domain, Type, [{both, WCDomain, WCType}|T]) ->
+ L1=length(Domain),
+ case catch regexp:matches(Domain, WCDomain) of
+ {match, []} ->
+ match_types(Domain, Type, T);
+ {match, [{1, L1}]} ->
+ L2=length(Type),
+ case catch regexp:matches(Type, WCType) of
+ {match, []} ->
+ match_types(Domain, Type, T);
+ {match, [{1, L2}]} ->
+ true;
+ _->
+ match_types(Domain, Type, T)
+ end;
+ _->
+ match_types(Domain, Type, T)
+ end;
+match_types(Domain, Type, [_|T]) ->
+ match_types(Domain, Type, T).
+
+%%------------------------------------------------------------
+%% function : validate_types
+%% Arguments: A sequence of CosNotification::EventType{}, i.e.,
+%% name-value pairs.
+%% Returns : ok |
+%% {'EXCEPTION', #'CosNotifyComm_InvalidEventType'{}}
+%%------------------------------------------------------------
+
+validate_types([]) ->
+ ok;
+validate_types([#'CosNotification_EventType'{domain_name=Do,type_name=Ty}|T])
+ when is_list(Do) andalso is_list(Ty) ->
+ validate_types(T);
+validate_types([H|_])
+ when is_record(H, 'CosNotification_EventType') ->
+ %% Not valid.
+ corba:raise(#'CosNotifyComm_InvalidEventType'{type=H});
+validate_types(_) ->
+ %% Wasn't even a correct input.
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/src/cosNotification_Grammar.yrl b/lib/cosNotification/src/cosNotification_Grammar.yrl
new file mode 100644
index 0000000000..98233bf92d
--- /dev/null
+++ b/lib/cosNotification/src/cosNotification_Grammar.yrl
@@ -0,0 +1,166 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%--------------------------------------------------------------------
+%% File : cosNotification_Grammar.yrl
+%% Purpose : Implement the constraint grammar for CosNotification filters.
+%%--------------------------------------------------------------------
+
+Nonterminals
+ '<toplevel>' '<constraint>' '<expr>' '<bool>' '<bool_or>' '<Ident>'
+ '<bool_and>' '<bool_compare>' '<expr_in>' '<expr_twiddle>' '<term>'
+ '<factor_not>' '<factor>' '<Component>' '<CompExt>' '<CompDot>' '<UnionVal>'.
+
+Terminals
+% 'dbslsh' 'bslshd'
+ 'bslsh' 'ident' 'string'
+ '_length' '_d''_type_id' '_repos_id'
+ 'not' 'or' 'and' 'num'
+ 'in' '~' '.' 'dollar'
+ 'ADDOP' 'RELOP' 'MULOP' 'default' 'exist'
+ 'TRUE' 'FALSE'
+ '(' ')' '[' ']' 'int'.
+
+Left 100 'or'.
+Left 200 'and'.
+%Nonassoc 300 'RELOP'. % '==', '!=', '<', '>', '<=', '=>'
+Left 300 'RELOP'.
+%Nonassoc 400 'in'.
+Left 400 'in'.
+%Nonassoc 500 '~'.
+Left 500 '~'.
+Left 600 'ADDOP'. % '+', '-'
+Left 700 'MULOP'. % '*', '/'
+Unary 800 'not'.
+Unary 900 'exist'.
+Unary 900 'default'.
+%Unary 900 'u-'. % unary minus
+
+Rootsymbol '<toplevel>'.
+Endsymbol '$end'.
+
+'<toplevel>' -> '$empty' : '$empty'.
+'<toplevel>' -> '<constraint>' : '$1'.
+
+'<constraint>' -> '<bool>' : '$1'.
+
+'<bool>' -> '<bool_or>' : '$1'.
+
+'<bool_or>' -> '<bool_or>' 'or' '<bool_and>' : {'or', '$1', '$3'}.
+'<bool_or>' -> '<bool_and>' : '$1'.
+
+'<bool_and>' -> '<bool_and>' 'and' '<bool_compare>' : {'and', '$1', '$3'}.
+'<bool_and>' -> '<bool_compare>' : '$1'.
+
+'<bool_compare>' -> '<expr_in>' 'RELOP' '<expr_in>' : {element(2, '$2'), '$1', '$3'}.
+'<bool_compare>' -> '<expr_in>' : '$1'.
+
+'<expr_in>' -> '<expr_twiddle>' : '$1'.
+'<expr_in>' -> '<expr_twiddle>' 'in' '<Ident>' : {'in', '$1', '$3'}.
+'<expr_in>' -> '<expr_twiddle>' 'in' 'dollar' '<Component>' : {'in', '$1', examin_comp({'component', '$4'})}.
+
+'<expr_twiddle>' -> '<expr>' : '$1'.
+'<expr_twiddle>' -> '<expr>' '~' '<expr>' : {'~', '$1', '$3'}.
+
+'<expr>' -> '<term>' : '$1'.
+'<expr>' -> '<expr>' 'ADDOP' '<term>' : {element(2, '$2'), '$1', '$3'}.
+
+'<term>' -> '<factor_not>' : '$1'.
+'<term>' -> '<term>' 'MULOP' '<factor_not>' : {element(2, '$2'), '$1', '$3'}.
+
+'<factor_not>' -> '<factor>' : '$1'.
+'<factor_not>' -> 'not' '<factor>' : {'not', '$2'}.
+
+'<factor>' -> '(' '<bool_or>' ')' : '$2'.
+'<factor>' -> 'num' : element(2, '$1').
+'<factor>' -> 'int' : element(2, '$1').
+'<factor>' -> 'string' : element(2, '$1').
+'<factor>' -> 'TRUE' : 'true'.
+'<factor>' -> 'FALSE' : 'false'.
+'<factor>' -> 'ADDOP' 'num' : create_unary(element(2, '$1'), element(2, '$2')).
+'<factor>' -> 'ADDOP' 'int' : create_unary(element(2, '$1'), element(2, '$2')).
+'<factor>' -> '<Ident>' : list_to_atom('$1').
+'<factor>' -> 'dollar' '<Component>' : examin_comp({component, '$2'}).
+'<factor>' -> 'default' 'dollar' '<Component>' : examin_comp({'default_component', '$3'}).
+'<factor>' -> 'exist' 'dollar' '<Component>' : examin_comp({'exist_component', '$3'}).
+
+%% The following rules are used to create Components. The format used is:
+%% [...]
+'<Component>' -> '.' '<CompDot>' : '$2'.
+'<Component>' -> '[' 'int' ']' '<CompExt>' : [{'arrindex', element(2, '$2')} | '$4']. %% CompArray
+'<Component>' -> '(' '<Ident>' ')' '<CompExt>' : [{'associd', '$2'} | '$4']. %%CompAssoc
+'<Component>' -> '<Ident>' '<CompExt>' : [{'varid', '$1'} | '$2']. %% run-time variable
+'<Component>' -> '$empty' : [].
+
+'<CompExt>' -> '.' '<CompDot>' : '$2'.
+'<CompExt>' -> '[' 'int' ']' '<CompExt>' : [{'arrindex', element(2, '$2')} | '$4']. %% CompArray
+'<CompExt>' -> '(' '<Ident>' ')' '<CompExt>' : [{'associd', '$2'} | '$4']. %%CompAssoc
+'<CompExt>' -> '$empty' : [].
+
+'<CompDot>' -> '<Ident>' '<CompExt>' : [{'dotid', '$1'} | '$2'].
+'<CompDot>' -> 'int' '<CompExt>' : [{'dotint', element(2, '$1')} | '$2']. %% ComPos
+'<CompDot>' -> '(' '<UnionVal>' ')' '<CompExt>' : ['$2' | '$4']. %% UnionPos
+'<CompDot>' -> '_length' : ['_length']. %% arrays or sequences ONLY
+'<CompDot>' -> '_d' : ['_d']. %% discriminated unions ONLY
+'<CompDot>' -> '_type_id' : ['_type_id']. %% ok if info can be obtained
+'<CompDot>' -> '_repos_id' : ['_repos_id']. %% ok if info can be obtained
+
+'<Ident>' -> 'ident' : element(2, '$1').
+'<Ident>' -> 'bslsh' 'ident' : element(2, '$2').
+
+'<UnionVal>' -> 'int' : {'uint', element(2, '$1')}.
+'<UnionVal>' -> 'ADDOP' 'int' : {'uint', create_unary(element(2, '$1'), element(2, '$2'))}.
+'<UnionVal>' -> 'string' : {'ustr', element(2, '$1')}.
+'<UnionVal>' -> '$empty': 'default'.
+
+Erlang code.
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% File : cosNotification_Grammar.erl
+%% Purpose : THIS FILE HAS BEEN GENERATED. DO NOT EDIT!!!!
+%%----------------------------------------------------------------------
+
+-include("CosNotification_Definitions.hrl").
+
+create_unary('+', Val) when is_number(Val) -> Val;
+create_unary('-', Val) when is_number(Val) -> -Val;
+create_unary(_, _) -> return_error(0, "syntax error").
+
+examin_comp({T, []}) ->
+ {T, '$empty'};
+examin_comp(V) ->
+ V.
+
diff --git a/lib/cosNotification/src/cosNotification_Scanner.erl b/lib/cosNotification/src/cosNotification_Scanner.erl
new file mode 100644
index 0000000000..e9c54319f0
--- /dev/null
+++ b/lib/cosNotification/src/cosNotification_Scanner.erl
@@ -0,0 +1,268 @@
+%%----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : cosNotification_Scanner.erl
+%% Purpose : Scan and pre-process a grammar.
+%%----------------------------------------------------------------------
+
+-module('cosNotification_Scanner').
+
+-export([scan/1]).
+
+scan(Str) ->
+ RSL = scan(Str, 1, [], any),
+ {ok, lists:reverse(RSL)}.
+
+
+%% Guard macros used at top scan functions only
+-define(is_number(X), X >= $0, X =< $9).
+-define(is_upper(X), X >= $A, X =< $Z).
+-define(is_lower(X), X >= $a, X =< $z).
+
+%%----------------------------------------------------------------------
+%% scan
+%%
+%% A-Z
+scan([X|Str], Line, Out, Type) when ?is_upper(X) ->
+ scan_name(Str, [X], Line, Out, Type);
+%% a-z
+scan([X|Str], Line, Out, Type) when ?is_lower(X) ->
+ scan_name(Str, [X], Line, Out, Type);
+%% 0-9
+scan([X|Str], Line, Out, Type) when ?is_number(X) ->
+ scan_number(Str, [X], Line, Out, Type);
+
+%% RELOP:s == != <= >= > <
+scan([$=,$= | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'RELOP', '=='} | Out], any);
+scan([$!,$= | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'RELOP', '!='} | Out], any);
+scan([$<,$= | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'RELOP', '<='} | Out], any);
+scan([$>,$= | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'RELOP', '>='} | Out], any);
+scan([$> | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'RELOP', '>'} | Out], any);
+scan([$< | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'RELOP', '<'} | Out], any);
+
+%% ADDOP:s + -
+scan([$+ | Str], Line, Out, Type) ->
+ scan(Str, Line, [{'ADDOP', '+'} | Out], Type);
+scan([$- | Str], Line, Out, Type) ->
+ scan(Str, Line, [{'ADDOP', '-'} | Out], Type);
+
+%% MULOP:s * /
+scan([$* | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'MULOP', '*'} | Out], any);
+scan([$/ | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'MULOP', '/'} | Out], any);
+
+%% TAB
+scan([9| T], Line, Out, Type) -> scan(T, Line, Out, Type);
+%% SP
+scan([32| T], Line, Out, Type) -> scan(T, Line, Out, Type);
+%% CR
+scan([$\r|Str], Line, Out, Type) ->
+ scan(Str, Line, Out, Type);
+%% LF
+scan([$\n|Str], Line, Out, Type) ->
+ scan(Str, Line+1, Out, Type);
+%% \\
+scan([92, 92 | Str], Line, Out, Type) ->
+ scan(Str, Line, [{'dbslsh', Line} | Out], Type);
+%% \'
+scan([92, 39 | Str], Line, Out, Type) ->
+ scan(Str, Line, [{'bslshd', Line} | Out], Type);
+%% '\'
+scan([92 | Str], Line, Out, Type) ->
+ scan(Str, Line, [{'bslsh', Line} | Out], Type);
+%% '_'
+scan([$_ | Str], Line, Out, dollar) ->
+ scan_name(Str, [$_], Line, Out, dollar);
+%% '$'
+scan([$$, 92 | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'bslsh', Line}, {'dollar', Line} | Out], dollar);
+scan([$$ | Str], Line, Out, _Type) ->
+ scan(Str, Line, [{'dollar', Line} | Out], dollar);
+scan([$"|Str], Line, Out, Type) ->
+ scan_const(char, Str, [], Line, Out, Type);
+scan([$'|Str], Line, Out, Type) ->
+ scan_const(string, Str, [], Line, Out, Type);
+
+%% Writing '+.<CompDot>' is not allowed ('+' or '-' are only allowed
+%% as unary for <UnionVal> (within a component) which must be en integer).
+scan([$. | Str], Line, [{'ADDOP', Op}|Out], _) ->
+ scan_frac(Str, [$.], Line, [{'ADDOP', Op}|Out], any);
+%% Must be a <CompDot>
+scan([$. | Str], Line, Out, dollar) ->
+ scan(Str, Line, [{'.',Line} | Out], dollar);
+%% Number
+scan([$. | Str], Line, Out, Type) ->
+ scan_frac(Str, [$.], Line, Out, Type);
+scan([C|Str], Line, Out, Type) ->
+ scan(Str, Line, [{list_to_atom([C]), Line} | Out], Type);
+
+scan([], _Line, Out, _Type) ->
+ Out.
+
+%%----------------------------------------------------------------------
+%% scan_name
+%%
+
+scan_number([X|Str], Accum, Line, Out, Type) when ?is_number(X) ->
+ scan_number(Str, [X|Accum], Line, Out, Type);
+scan_number([X|Str], Accum, Line, Out, dollar) when X==$. ->
+ scan(Str, Line, [{'.', Line},
+ {'int', list_to_integer(lists:reverse(Accum))} | Out], dollar);
+scan_number([X|Str], Accum, Line, Out, Type) when X==$. ->
+ scan_frac(Str, [X|Accum], Line, Out, Type);
+scan_number([X|Str], Accum, Line, Out, Type) when X==$e ->
+ scan_exp(Str, [X|Accum], Line, Out, Type);
+scan_number([X|Str], Accum, Line, Out, Type) when X==$E ->
+ scan_exp(Str, [X|Accum], Line, Out, Type);
+scan_number(Str, Accum, Line, Out, Type) ->
+ scan(Str, Line, [{'int', list_to_integer(lists:reverse(Accum))} | Out], Type).
+
+
+%% Floating point number scan.
+%%
+%% Non trivial scan. A float consists of an integral part, a
+%% decimal point, a fraction part, an e or E and a signed integer
+%% exponent. Either the integer part or the fraction part but not
+%% both may be missing, and either the decimal point or the
+%% exponent part but not both may be missing. The exponent part
+%% must consist of an e or E and a possibly signed exponent.
+%%
+%% Analysis shows that "1." ".7" "1e2" ".5e-3" "1.7e2" "1.7e-2"
+%% is allowed and "1" ".e9" is not. The sign is only allowed just
+%% after an e or E. The scanner reads a number as an integer
+%% until it encounters a "." so the integer part only error case
+%% will not be caught in the scanner (but rather in expression
+%% evaluation)
+
+scan_frac([$e | _Str], [$.], _Line, _Out, _Type) ->
+ {error, "illegal_float"};
+scan_frac([$E | _Str], [$.], _Line, _Out, _Type) ->
+ {error, "illegal_float"};
+scan_frac(Str, Accum, Line, Out, Type) ->
+ scan_frac2(Str, Accum, Line, Out, Type).
+
+scan_frac2([X|Str], Accum, Line, Out, Type) when ?is_number(X) ->
+ scan_frac2(Str, [X|Accum], Line, Out, Type);
+scan_frac2([X|Str], Accum, Line, Out, Type) when X==$e ->
+ scan_exp(Str, [X|Accum], Line, Out, Type);
+scan_frac2([X|Str], Accum, Line, Out, Type) when X==$E ->
+ scan_exp(Str, [X|Accum], Line, Out, Type);
+%% Since '.2' is allowed, we add '0' in front to be sure (erlang do not allow
+%% list_to_float(".2") and list_to_float("0.2") eq. list_to_float("00.2")).
+scan_frac2(Str, Accum, Line, Out, Type) ->
+ scan(Str, Line, [{'num', list_to_float([$0|lists:reverse(Accum)])} | Out], Type).
+
+scan_exp([X|Str], Accum, Line, Out, Type) when X==$- ->
+ scan_exp2(Str, [X|Accum], Line, Out, Type);
+scan_exp(Str, Accum, Line, Out, Type) ->
+ scan_exp2(Str, Accum, Line, Out, Type).
+
+scan_exp2([X|Str], Accum, Line, Out, Type) when ?is_number(X) ->
+ scan_exp2(Str, [X|Accum], Line, Out, Type);
+%% Since '.2' is allowed, we add '0' in front to be sure (erlang do not allow
+%% list_to_float(".2")).
+scan_exp2(Str, Accum, Line, Out, Type) ->
+ scan(Str, Line, [{'num', list_to_float([$0|lists:reverse(Accum)])} | Out], Type).
+
+
+scan_name([X|Str], Accum, Line, Out, Type) when ?is_upper(X) ->
+ scan_name(Str, [X|Accum], Line, Out, Type);
+scan_name([X|Str], Accum, Line, Out, Type) when ?is_lower(X) ->
+ scan_name(Str, [X|Accum], Line, Out, Type);
+scan_name([X|Str], Accum, Line, Out, Type) when ?is_number(X) ->
+ scan_name(Str, [X|Accum], Line, Out, Type);
+scan_name([$_|Str], Accum, Line, Out, dollar) ->
+ scan_name(Str, [$_|Accum], Line, Out, dollar);
+scan_name(S, Accum, Line, [{bslsh,LL} | Out], Type) ->
+ %% An escaped identifier.
+ L = lists:reverse(Accum),
+ scan(S, Line, [{'ident', L}, {bslsh,LL} | Out], Type);
+scan_name(S, Accum, Line, Out, Type) ->
+ L = lists:reverse(Accum),
+ {X, NewType} = case check_name(L) of
+ false ->
+ {{'ident', L}, Type};
+ _ ->
+ {{list_to_atom(L), Line}, any}
+ end,
+ scan(S, Line, [X | Out], NewType).
+
+%% Shall scan a constant
+scan_const(char, [$" | Rest], Accum, Line, Out, Type) ->
+ scan(Rest, Line,
+ [{'ident', list_to_atom(lists:reverse(Accum))} | Out], Type);
+scan_const(char, [], _Accum, _Line, Out, _Type) -> %% Bad string
+% {error, "bad_string"};
+ Out;
+scan_const(string, [$' | Rest], Accum, Line, Out, Type) ->
+ scan(Rest, Line,
+ [{'string', lists:reverse(Accum)} | Out], Type);
+scan_const(Mode, [$\\, C | Rest], Accum, Line, Out, Type) ->
+ case escaped_char(C) of
+ error ->
+ %% Bad escape character
+ %% {error, "bad_escape_character"};
+ scan_const(Mode, Rest, [C | Accum], Line, Out, Type);
+ EC ->
+ scan_const(Mode, Rest, [EC | Accum], Line, Out, Type)
+ end;
+scan_const(Mode, [C | Rest], Accum, Line, Out, Type) ->
+ scan_const(Mode, Rest, [C | Accum], Line, Out, Type).
+
+%% Escaped character. Escaped chars are repr as two characters in the
+%% input list of letters and this is translated into one char.
+escaped_char($n) -> $\n;
+escaped_char($t) -> $\t;
+escaped_char($v) -> $\v;
+escaped_char($b) -> $\b;
+escaped_char($r) -> $ ;
+escaped_char($f) -> $\f;
+escaped_char($a) -> $\a;
+escaped_char($\\) -> $\\;
+escaped_char($?) -> $?;
+escaped_char($') -> $';
+escaped_char($") -> $";
+%% Error
+escaped_char(_Other) -> error.
+
+
+check_name("exist") -> true;
+check_name("default") -> true;
+check_name("_length") -> true;
+check_name("_d") -> true;
+check_name("_type_id") -> true;
+check_name("_repos_id") -> true;
+check_name("not") -> true;
+check_name("or") -> true;
+check_name("and") -> true;
+check_name("FALSE") -> true;
+check_name("TRUE") -> true;
+check_name("in") -> true;
+check_name(_) -> false.
+
+
diff --git a/lib/cosNotification/src/cosNotification_eventDB.erl b/lib/cosNotification/src/cosNotification_eventDB.erl
new file mode 100644
index 0000000000..89332d53f2
--- /dev/null
+++ b/lib/cosNotification/src/cosNotification_eventDB.erl
@@ -0,0 +1,1350 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : cosNotification_eventDB.erl
+%% Purpose :
+%% Purpose : This module is supposed to centralize Event storage.
+%% Comments:
+%% * Setting Order Policy to AnyOrder eq. Priority order
+%%
+%% * Setting Discard Policy to AnyOrder eq. RejectNewEvents.
+%%
+%% * DB ordering: Since the deliver- and discard-order may differ we need
+%% two ets-tables, both of type 'ordered_set'. They contain:
+%% - table 1 (T1): deliver order key and the associated event.
+%% - table 2 (T2): discard order key.
+%%
+%% When adding a new event we add, if necessary, related keys in T2.
+%% For example, if we should discard events in FIFO order, the delivery
+%% order may be set to Priority order. If the Max Event limit is reached
+%% we first look in T2 to find out which event to discard by using and
+%% reorder the key elements. T2 gives {TimeStamp, Priority}, which is used
+%% to lookup in T1 as {Priority, TimeStamp}.
+%% A TimeStamp is always included in the DB keys, even if FIFO or LIFO
+%% is used, since lots of events probably will have the same prioity and
+%% with a little bit of bad luck some events will never be delivered.
+%%
+%% Note: deliver order AnyOrder and PriorityOrder is equal since the later
+%% is defined as default.
+%% discard order AnyOrder and RejectNewEvents is equal since the later
+%% is defined as default.
+%% The keys used is ('-' indicates T2 is not needed and, thus, not instantiated):
+%%
+%% T1 policy T1 Key T2 Policy T2 Key
+%% ------------------------------------------------------------------
+%% DeadlineOrder {DL, Key, Prio} PriorityOrder {Prio, Key, DL}
+%% DeadlineOrder {DL, Key} FifoOrder {Key, DL}
+%% DeadlineOrder {DL, Key} LifoOrder {Key, DL}
+%% DeadlineOrder {DL, Key} RejectNewEvents -
+%% DeadlineOrder {DL, Key} DeadlineOrder -
+%% FifoOrder {Key, DL} DeadlineOrder {DL, Key}
+%% FifoOrder {Key, Prio} PriorityOrder {Prio, Key}
+%% FifoOrder Key RejectNewEvents -
+%% FifoOrder Key Fifo -
+%% FifoOrder Key Lifo -
+%% PriorityOrder {Prio, Key, DL} DeadlineOrder {DL, Key, Prio}
+%% PriorityOrder {Prio, Key} Fifo {Key, Prio}
+%% PriorityOrder {Prio, Key} Lifo {Key, Prio}
+%% PriorityOrder {Prio, Key} RejectNewEvents -
+%% ------------------------------------------------------------------
+%% DL == Deadline, Key == TimeStamp, Prio == Priority
+%%
+%% NOTE: If defined, the Discard DB Keys are the same as in Event DB, except
+%% that the first and last Key change place. {K1,K2}<->{K2,K1} and
+%% {K1,K2,K3}<->{K3,K2,K1}.
+%%----------------------------------------------------------------------
+
+-module(cosNotification_eventDB).
+
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/include/ifr_types.hrl").
+-include_lib("cosTime/include/TimeBase.hrl").
+
+%% Application files
+-include("CosNotification.hrl").
+-include("CosNotifyChannelAdmin.hrl").
+-include("CosNotifyComm.hrl").
+-include("CosNotifyFilter.hrl").
+
+-include("CosNotification_Definitions.hrl").
+
+%%--------------- EXPORTS ------------------------------------
+%% Internal Filter Functions
+-export([validate_event/5,
+ create_db/4,
+ destroy_db/1,
+ get_event/1,
+ get_event/2,
+ get_events/2,
+ get_events/3,
+ delete_events/1,
+ update/2,
+ update/4,
+ add_event/2,
+ add_event/4,
+ add_and_get_event/2,
+ add_and_get_event/3,
+ add_and_get_event/4,
+ add_and_get_event/5,
+ gc_events/2,
+ gc_events_local/4,
+ gc_start/2,
+ filter_events/2,
+ filter_events/3,
+ status/2]).
+
+%%--------------- DATA STRUCTURES ----------------------------
+-record(dbRef, {orderRef, discardRef, orderPolicy, discardPolicy,
+ defPriority, maxEvents, defStopT, startTsupport,
+ stopTsupport, gcTime, gcLimit, timeRef}).
+
+
+
+%%--------------- DEFINES ------------------------------------
+
+-define(CreateRef(OR, DR, O, D, DP, ME, DS, StaT, StoT, GT, GL, TR),
+ #dbRef{orderRef=OR, discardRef=DR, orderPolicy=O, discardPolicy=D,
+ defPriority=DP, maxEvents=ME, defStopT=DS, startTsupport=StaT,
+ stopTsupport=StoT, gcTime=GT, gcLimit=round(ME*GL/100),
+ timeRef=TR}).
+
+
+-define(get_OrderP(DR), DR#dbRef.orderPolicy).
+-define(get_DiscardP(DR), DR#dbRef.discardPolicy).
+-define(get_OrderRef(DR), DR#dbRef.orderRef).
+-define(get_DiscardRef(DR), DR#dbRef.orderRef).
+-define(get_DefPriority(DR), DR#dbRef.defPriority).
+-define(get_MaxEvents(DR), DR#dbRef.maxEvents).
+-define(get_DefStopT(DR), DR#dbRef.defStopT).
+-define(get_StartTsupport(DR), DR#dbRef.startTsupport).
+-define(get_StopTsupport(DR), DR#dbRef.stopTsupport).
+-define(get_GCTime(DR), DR#dbRef.gcTime).
+-define(get_GCLimit(DR), DR#dbRef.gcLimit).
+-define(get_TimeRef(DR), DR#dbRef.timeRef).
+
+-define(set_OrderP(DR, O), DR#dbRef{orderPolicy = O}).
+-define(set_DiscardP(DR, D), DR#dbRef{discardPolicy = D}).
+-define(set_OrderRef(DR, E), DR#dbRef{orderRef = E}).
+-define(set_DiscardRef(DR, E), DR#dbRef{orderRef = E}).
+-define(set_DefPriority(DR, DP), DR#dbRef{defPriority = DP}).
+-define(set_MaxEvents(DR, ME), DR#dbRef{maxEvents = ME}).
+-define(set_DefStopT(DR, DS), DR#dbRef{defStopT = DS}).
+-define(set_StartTsupport(DR, B), DR#dbRef{startTsupport = B}).
+-define(set_StopTsupport(DR, B), DR#dbRef{stopTsupport = B}).
+
+-define(is_StartTNotSupported(DR), DR#dbRef.startTsupport == false).
+-define(is_StopTNotSupported(DR), DR#dbRef.stopTsupport == false).
+-define(is_TimeoutNotUsed(DR), DR#dbRef.defStopT == 0).
+
+
+%%------------------------------------------------------------
+%% function : status
+%% Arguments: DBRef
+%% Key - which information we want.
+%% Returns : Data related to the Key.
+%%------------------------------------------------------------
+status(DBRef, eventCounter) ->
+ ets:info(?get_OrderRef(DBRef), size);
+status(DBRef, {batchLimit, Limit}) ->
+ case ets:info(?get_OrderRef(DBRef), size) of
+ Current when is_integer(Current) andalso Current >= Limit ->
+ ?debug_print("BATCH LIMIT (~p) REACHED, CONTAINS: ~p~n", [Limit, Current]),
+ true;
+ _Other ->
+ ?debug_print("BATCH LIMIT (~p) NOT REACHED, CONTAINS: ~p~n",
+ [Limit, _Other]),
+ false
+ end;
+status(DBRef, {batchLimit, Limit, TemporaryMax}) ->
+ case ets:info(?get_OrderRef(DBRef), size) of
+ Current when is_integer(Current) andalso Current >= TemporaryMax ->
+ ?debug_print("MAX LIMIT (~p) REACHED, CONTAINS: ~p~n",
+ [TemporaryMax, Current]),
+ true;
+ Current when is_integer(Current) andalso Current >= Limit ->
+ ?debug_print("BATCH LIMIT (~p) REACHED, CONTAINS: ~p~n", [Limit, Current]),
+ true;
+ _Other ->
+ ?debug_print("BATCH LIMIT (~p) NOT REACHED, CONTAINS: ~p~n",
+ [Limit, _Other]),
+ false
+ end;
+status(_, _) ->
+ error.
+
+
+%%------------------------------------------------------------
+%% function : gc_events_local
+%% Arguments: DBRef
+%% Returns :
+%% Comment : This function is intended for "emergency" GC, i.e.,
+%% when the DB must discard events we should first try
+%% to remove events with expired deadlines.
+%%------------------------------------------------------------
+gc_events_local(_, _, false, _) ->
+ ok;
+gc_events_local(_, _, _, 0) ->
+ ok;
+gc_events_local(ORef, DRef, _, _) ->
+ gc_loop(ets:first(ORef), ORef, DRef).
+
+%%------------------------------------------------------------
+%% function : gc_events
+%% Arguments: DBRef
+%% Priority - 'low', 'medium' or 'high'; will determine
+%% how important a fast gc is.
+%% Returns :
+%% Comment : This function is intended for background GC.
+%%------------------------------------------------------------
+gc_events(DBRef, _Priority) when ?is_TimeoutNotUsed(DBRef) ->
+ ok;
+gc_events(DBRef, _Priority) when ?is_StopTNotSupported(DBRef) ->
+ ok;
+gc_events(DBRef, Priority) ->
+ {M,S,U} = now(),
+ case get(oe_GC_timestamp) of
+ Num when {M,S,U} > Num ->
+ put(oe_GC_timestamp, {M,S+?get_GCTime(DBRef),U}),
+ spawn_link(?MODULE, gc_start, [DBRef, Priority]);
+ _->
+ ok
+ end.
+
+
+%%------------------------------------------------------------
+%% function : gc_start
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+gc_start(#dbRef{orderRef = ORef, discardRef = DRef}, Priority) ->
+ process_flag(priority, Priority),
+ gc_loop(ets:first(ORef), ORef, DRef).
+
+gc_loop('$end_of_table', _, _) ->
+ ok;
+gc_loop(Key, ORef, DRef) ->
+ [{Keys,DL,_,_,_}]=ets:lookup(ORef, Key),
+ case check_deadline(DL) of
+ true when DRef == undefined ->
+ ets:delete(ORef, Key);
+ true ->
+ ets:delete(ORef, Key),
+ gc_discard_DB(Keys, DRef);
+ _ ->
+ ok
+ end,
+ gc_loop(ets:next(ORef, Key), ORef, DRef).
+
+gc_discard_DB({Key1, Key2}, DRef) ->
+ ets:delete(DRef, {Key2, Key1});
+gc_discard_DB({Key1, Key2, Key3}, DRef) ->
+ ets:delete(DRef, {Key3, Key2, Key1}).
+
+%%------------------------------------------------------------
+%% function : create_FIFO_Key
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+create_FIFO_Key() ->
+ {M, S, U} = erlang:now(),
+ -M*1000000000000 - S*1000000 - U.
+
+%%------------------------------------------------------------
+%% function : convert_FIFO_Key
+%% Arguments:
+%% Returns : A now tuple
+%% Comment : Used when we must reuse a timestamp, i.e., only
+%% when we must reorder the DB.
+%%------------------------------------------------------------
+convert_FIFO_Key(Key) ->
+ K = abs(Key),
+ Secs = trunc(K/1000000),
+ M = trunc(K/1000000000000),
+ S = Secs-M*1000000,
+ U = K - S*1000000-M*1000000000000,
+ {M, S, U}.
+
+%%------------------------------------------------------------
+%% function : extract_priority
+%% Arguments: Event
+%% Defalt Value
+%% Mapping Filter Value
+%% - false value not needed (depends on QoS type)
+%% - undefined value needed but no filter associated.
+%% Returns :
+%%------------------------------------------------------------
+extract_priority(_, _, false) ->
+ false;
+extract_priority(#'CosNotification_StructuredEvent'
+ {header = #'CosNotification_EventHeader'
+ {variable_header = VH}}, DefPriority, undefined) ->
+ extract_value(VH, ?not_Priority, DefPriority);
+%% Maybe a unstructured event.
+extract_priority(_, DefPriority, undefined) ->
+ DefPriority;
+extract_priority(_, _, PriorityOverride) ->
+ %% Must have an associated MappingFilter for Priority.
+ PriorityOverride.
+
+%%------------------------------------------------------------
+%% function : extract_start_time
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+extract_start_time(_, false, _) ->
+ false;
+extract_start_time(#'CosNotification_StructuredEvent'
+ {header = #'CosNotification_EventHeader'
+ {variable_header = VH}}, _, TRef) ->
+ ST = case extract_value(VH, ?not_StartTime, undefined) of
+ UTC when is_record(UTC, 'TimeBase_UtcT') ->
+ UTC;
+ _ ->
+ false
+ end,
+ convert_time(ST, TRef, now());
+extract_start_time(_, _, _) ->
+ false.
+
+%%------------------------------------------------------------
+%% function : extract_deadline
+%% Arguments: Structured Event
+%% Default Timeout Value - TimeT or UtcT (see cosTime).
+%% StopTSupported - boolean().
+%% TRef - reference to TimeService
+%% Mapping Filter Value
+%% - false eq. value not needed (depends on QoS type)
+%% - undefined eq. value needed but no filter associated.
+%% Now - used when we want to reuse old TimeStamp which
+%% must be done when changing QoS.
+%% Returns : A modified return from now().
+%%------------------------------------------------------------
+extract_deadline(_, _, _, _, false) ->
+ false;
+extract_deadline(Event, DefaultT, StopTSupported, TRef, MappingVal) ->
+ extract_deadline(Event, DefaultT, StopTSupported, TRef, MappingVal, now()).
+
+extract_deadline(_, _, _, _, false, _) ->
+ false;
+extract_deadline(#'CosNotification_StructuredEvent'
+ {header = #'CosNotification_EventHeader'
+ {variable_header = VH}}, DefaultT, StopTSupported,
+ TRef, undefined, Now) ->
+ DL = case extract_value(VH, ?not_Timeout, undefined) of
+ undefined when StopTSupported == true, TRef =/= undefined ->
+ case extract_value(VH, ?not_StopTime, undefined) of
+ undefined ->
+ DefaultT;
+ DefinedTime ->
+ DefinedTime
+ end;
+ undefined ->
+ DefaultT;
+ DefinedTime ->
+ DefinedTime
+ end,
+ convert_time(DL, TRef, Now);
+%% Maybe a unstructured event.
+extract_deadline(_, Time, _, TRef, undefined, Now) ->
+ convert_time(Time, TRef, Now);
+extract_deadline(_, _, _, TRef, DOverride, Now) ->
+ %% Must have an associated MappingFilter defining a Deadline.
+ convert_time(DOverride, TRef, Now).
+
+convert_time(0, _, _) ->
+ false;
+convert_time(UTC, TRef, {M,S,U}) when is_record(UTC, 'TimeBase_UtcT') ->
+ case catch get_time_diff(UTC, TRef) of
+ {'EXCEPTION', _} ->
+ false;
+ {'EXIT', _} ->
+ false;
+ DL ->
+ MicroSecs = round(DL/10),
+ Secs = round(MicroSecs/1000000),
+ MegaSecs = round(Secs/1000000),
+ {-M-MegaSecs, -S-Secs+MegaSecs, -U-MicroSecs+Secs}
+ end;
+convert_time(DL, _, {M,S,U}) when is_integer(DL) ->
+ MicroSecs = round(DL/10),
+ Secs = round(MicroSecs/1000000),
+ MegaSecs = round(Secs/1000000),
+ {-M-MegaSecs, -S-Secs+MegaSecs, -U-MicroSecs+Secs};
+convert_time(_, _, _) ->
+ false.
+
+
+get_time_diff(UTC, TRef) ->
+ UTO = 'CosTime_TimeService':universal_time(TRef),
+ UTO2 = 'CosTime_TimeService':uto_from_utc(TRef, UTC),
+ TIO = 'CosTime_UTO':time_to_interval(UTO, UTO2),
+ #'TimeBase_IntervalT'{lower_bound=LB, upper_bound = UB} =
+ 'CosTime_TIO':'_get_time_interval'(TIO),
+ UB-LB.
+
+check_deadline(DL) when is_tuple(DL) ->
+ {M,S,U} = now(),
+ DL >= {-M,-S,-U};
+check_deadline(_DL) ->
+ %% This case will cover if no timeout is set.
+ false.
+
+check_start_time(ST) when is_tuple(ST) ->
+ {M,S,U} = now(),
+ ST >= {-M,-S,-U};
+check_start_time(_ST) ->
+ %% This case will cover if no earliest delivery time is set.
+ true.
+
+%%------------------------------------------------------------
+%% function : extract_value
+%% Arguments: A Property Sequence
+%% ID - wanted property string()
+%% Other - default-value.
+%% Returns : Value associated with given ID or default value.
+%%------------------------------------------------------------
+extract_value([], _, Other) ->
+ Other;
+extract_value([#'CosNotification_Property'{name=ID, value=V}|_], ID, _) ->
+ any:get_value(V);
+extract_value([_H|T], ID, Other) ->
+ extract_value(T, ID, Other).
+
+%%------------------------------------------------------------
+%% function : get_event
+%% Arguments:
+%% Returns :
+%%------------------------------------------------------------
+get_event(DBRef) ->
+ get_event(DBRef, true).
+get_event(DBRef, Delete) ->
+ case get_events(DBRef, 1, Delete) of
+ {[], false} ->
+ {[], false};
+ {[], false, Keys} ->
+ {[], false, Keys};
+ {[Event], Bool} ->
+ {Event, Bool};
+ {[Event], Bool, Keys} ->
+ {Event, Bool, Keys}
+ end.
+
+%%------------------------------------------------------------
+%% function : get_events
+%% Arguments:
+%% Returns : A list of events (possibly empty) and a boolean
+%% indicating if event found.
+%% Comments : Try to extract Max events from the database.
+%%------------------------------------------------------------
+get_events(#dbRef{orderRef = ORef, discardRef = DRef}, Max) ->
+ event_loop(ets:last(ORef), ORef, DRef, Max, [], [], true).
+
+get_events(#dbRef{orderRef = ORef, discardRef = DRef}, Max, Delete) ->
+ event_loop(ets:last(ORef), ORef, DRef, Max, [], [], Delete).
+
+event_loop('$end_of_table', _, _, _, [], _, true) ->
+ {[], false};
+event_loop('$end_of_table', _, _, _, [], [], _) ->
+ {[], false, []};
+event_loop('$end_of_table', _ORef, _, _, Accum, _Keys, true) ->
+ {lists:reverse(Accum), true};
+event_loop('$end_of_table', _ORef, _, _, Accum, Keys, _) ->
+ {lists:reverse(Accum), true, Keys};
+event_loop(_, _ORef, _, 0, [], _Keys, true) ->
+ %% Only possible if some tries to pull a sequence of 0 events.
+ %% Should we really test for this case?
+ {[], false};
+event_loop(_, _ORef, _, 0, [], Keys, _) ->
+ {[], false, Keys};
+event_loop(_, _ORef, _, 0, Accum, _Keys, true) ->
+ {lists:reverse(Accum), true};
+event_loop(_, _ORef, _, 0, Accum, Keys, _) ->
+ {lists:reverse(Accum), true, Keys};
+event_loop(Key, ORef, undefined, Left, Accum, Keys, Delete) ->
+ [{_,DL,ST,_PO,Event}]=ets:lookup(ORef, Key),
+ case check_deadline(DL) of
+ true ->
+ ets:delete(ORef, Key),
+ event_loop(ets:prev(ORef, Key), ORef, undefined,
+ Left, Accum, Keys, Delete);
+ false ->
+ case check_start_time(ST) of
+ true when Delete == true ->
+ ets:delete(ORef, Key),
+ event_loop(ets:prev(ORef, Key), ORef, undefined,
+ Left-1, [Event|Accum], Keys, Delete);
+ true ->
+ event_loop(ets:prev(ORef, Key), ORef, undefined,
+ Left-1, [Event|Accum], [{ORef, Key}|Keys], Delete);
+ false ->
+ event_loop(ets:prev(ORef, Key), ORef, undefined,
+ Left, Accum, Keys, Delete)
+ end
+ end;
+event_loop({Key1, Key2}, ORef, DRef, Left, Accum, Keys, Delete) ->
+ [{_,DL,ST,_PO,Event}]=ets:lookup(ORef, {Key1, Key2}),
+ case check_deadline(DL) of
+ true ->
+ ets:delete(ORef, {Key1, Key2}),
+ ets:delete(DRef, {Key2, Key1}),
+ event_loop(ets:prev(ORef, {Key1, Key2}), ORef, DRef,
+ Left, Accum, Keys, Delete);
+ false ->
+ case check_start_time(ST) of
+ true when Delete == true ->
+ ets:delete(ORef, {Key1, Key2}),
+ ets:delete(DRef, {Key2, Key1}),
+ event_loop(ets:prev(ORef, {Key1, Key2}), ORef, DRef,
+ Left-1, [Event|Accum], Keys, Delete);
+ true ->
+ event_loop(ets:prev(ORef, {Key1, Key2}), ORef, DRef,
+ Left-1, [Event|Accum],
+ [{ORef, {Key1, Key2}}, {DRef, {Key2, Key1}}|Keys],
+ Delete);
+ false ->
+ event_loop(ets:prev(ORef, {Key1, Key2}), ORef, DRef,
+ Left, Accum, Keys, Delete)
+ end
+ end;
+event_loop({Key1, Key2, Key3}, ORef, DRef, Left, Accum, Keys, Delete) ->
+ [{_,DL,ST,_PO,Event}]=ets:lookup(ORef, {Key1, Key2, Key3}),
+ case check_deadline(DL) of
+ true ->
+ ets:delete(ORef, {Key1, Key2, Key3}),
+ ets:delete(DRef, {Key3, Key2, Key1}),
+ event_loop(ets:prev(ORef, {Key1, Key2, Key3}), ORef, DRef,
+ Left, Accum, Keys, Delete);
+ false ->
+ case check_start_time(ST) of
+ true when Delete == true ->
+ ets:delete(ORef, {Key1, Key2, Key3}),
+ ets:delete(DRef, {Key3, Key2, Key1}),
+ event_loop(ets:prev(ORef, {Key1, Key2, Key3}), ORef, DRef,
+ Left-1, [Event|Accum], Keys, Delete);
+ true ->
+ event_loop(ets:prev(ORef, {Key1, Key2, Key3}), ORef, DRef,
+ Left-1, [Event|Accum],
+ [{ORef, {Key1, Key2, Key3}},
+ {DRef, {Key3, Key2, Key1}}|Keys], Delete);
+ false ->
+ event_loop(ets:prev(ORef, {Key1, Key2, Key3}), ORef, DRef,
+ Left, Accum, Keys, Delete)
+ end
+ end.
+
+%%------------------------------------------------------------
+%% function : delete_events
+%% Arguments: EventList - what's returned by get_event, get_events
+%% and add_and_get_event.
+%% Returns :
+%% Comment : Shall be invoked when it's safe to premanently remove
+%% the events found in the EventList.
+%%
+%%------------------------------------------------------------
+delete_events([]) ->
+ ok;
+delete_events([{DB, Key}|T]) ->
+ ets:delete(DB, Key),
+ delete_events(T).
+
+%%------------------------------------------------------------
+%% function : update
+%% Arguments:
+%% Returns :
+%% Comment : As default we shall deliver Events in Priority order.
+%% Hence, if AnyOrder set we will still deliver in
+%% Priority order.
+%%------------------------------------------------------------
+update(undefined, _QoS) ->
+ ok;
+update(DBRef, QoS) ->
+ update(DBRef, QoS, undefined, undefined).
+
+update(DBRef, QoS, LifeFilter, PrioFilter) ->
+ case updated_order(DBRef, ?not_GetOrderPolicy(QoS)) of
+ false ->
+ case updated_discard(DBRef, ?not_GetDiscardPolicy(QoS)) of
+ false ->
+ DBR2 = ?set_DefPriority(DBRef, ?not_GetPriority(QoS)),
+ DBR3 = ?set_MaxEvents(DBR2, ?not_GetMaxEventsPerConsumer(QoS)),
+ DBR4 = ?set_DefStopT(DBR3, ?not_GetTimeout(QoS)),
+ DBR5 = ?set_StartTsupport(DBR4, ?not_GetStartTimeSupported(QoS)),
+ DBR6 = ?set_StopTsupport(DBR5, ?not_GetStopTimeSupported(QoS)),
+ case ets:info(?get_OrderRef(DBR6), size) of
+ N when N =< ?get_MaxEvents(DBR6) ->
+ %% Even if the QoS MaxEvents have been changed
+ %% we don't reach the limit.
+ DBR6;
+ N ->
+ %% The QoS MaxEvents must have been decreased.
+ discard_events(DBR6, N-?get_MaxEvents(DBR6)),
+ DBR6
+ end;
+ true ->
+ destroy_discard_db(DBRef),
+ NewDBRef = create_db(QoS, ?get_GCTime(DBRef), ?get_GCLimit(DBRef),
+ ?get_TimeRef(DBRef)),
+ move_events(DBRef, NewDBRef, ets:first(?get_OrderRef(DBRef)),
+ LifeFilter, PrioFilter)
+ end;
+ true ->
+ destroy_discard_db(DBRef),
+ NewDBRef = create_db(QoS, ?get_GCTime(DBRef), ?get_GCLimit(DBRef),
+ ?get_TimeRef(DBRef)),
+ move_events(DBRef, NewDBRef, ets:first(?get_OrderRef(DBRef)),
+ LifeFilter, PrioFilter)
+ end.
+
+updated_order(#dbRef{orderPolicy = Equal}, Equal) -> false;
+updated_order(#dbRef{orderPolicy = ?not_PriorityOrder}, ?not_AnyOrder) -> false;
+updated_order(#dbRef{orderPolicy = ?not_AnyOrder}, ?not_PriorityOrder) -> false;
+updated_order(_, _) -> true.
+
+updated_discard(#dbRef{discardPolicy = Equal}, Equal) -> false;
+updated_discard(#dbRef{discardPolicy = ?not_RejectNewEvents}, ?not_AnyOrder) -> false;
+updated_discard(#dbRef{discardPolicy = ?not_AnyOrder}, ?not_RejectNewEvents) -> false;
+updated_discard(_, _) -> true.
+
+move_events(DBRef, NewDBRef, '$end_of_table', _, _) ->
+ destroy_order_db(DBRef),
+ case ets:info(?get_OrderRef(NewDBRef), size) of
+ N when N =< ?get_MaxEvents(NewDBRef) ->
+ %% Even if the QoS MaxEvents have been changed
+ %% we don't reach the limit.
+ NewDBRef;
+ N ->
+ %% The QoS MaxEvents must have been decreased.
+ discard_events(DBRef, N-?get_MaxEvents(NewDBRef)),
+ NewDBRef
+ end;
+move_events(DBRef, NewDBRef, Key, LifeFilter, PrioFilter) ->
+ [{Keys, DeadLine, StartTime, PriorityOverride, Event}] =
+ ets:lookup(?get_OrderRef(DBRef), Key),
+ case check_deadline(DeadLine) of
+ true ->
+ ok;
+ _->
+ write_event(?get_OrderP(DBRef),
+ {Keys, DeadLine, StartTime, PriorityOverride, Event},
+ DBRef, NewDBRef, Key, LifeFilter, PrioFilter)
+ end,
+ ets:delete(?get_OrderRef(DBRef), Key),
+ move_events(DBRef, NewDBRef, ets:next(?get_OrderRef(DBRef), Key),
+ LifeFilter, PrioFilter).
+
+%% We cannot use do_add_event directly since we MUST lookup the timestamp (TS).
+write_event(?not_DeadlineOrder, {{_, TS, _Prio}, DL, ST, PO, Event}, _DBRef, NewDBRef,
+ _Key, _LifeFilter, _PrioFilter) ->
+ StartT = update_starttime(NewDBRef, Event, ST),
+ %% Deadline and Priority previously extracted.
+ do_add_event(NewDBRef, Event, TS, DL, StartT, PO);
+write_event(?not_DeadlineOrder, {{_, TS}, DL, _ST, PO, Event}, _DBRef, NewDBRef,
+ _Key, _LifeFilter, PrioFilter) ->
+ %% Priority not previously extracted.
+ POverride = update_priority(NewDBRef, PrioFilter, Event, PO),
+ StartT = extract_start_time(Event, ?get_StartTsupport(NewDBRef),
+ ?get_TimeRef(NewDBRef)),
+ do_add_event(NewDBRef, Event, TS, DL, StartT, POverride);
+write_event(?not_FifoOrder, {{TS, _PorD}, DL, ST, PO, Event}, _DBRef, NewDBRef,
+ _Key, LifeFilter, PrioFilter) ->
+ %% Priority or Deadline have been extracted before but we cannot tell which.
+ POverride = update_priority(NewDBRef, PrioFilter, Event, PO),
+ DeadL = update_deadline(NewDBRef, LifeFilter, Event, TS, DL),
+ StartT = update_starttime(NewDBRef, Event, ST),
+ do_add_event(NewDBRef, Event, TS, DeadL, StartT, POverride);
+write_event(?not_FifoOrder, {TS, DL, ST, PO, Event}, _DBRef, NewDBRef,
+ _Key, LifeFilter, PrioFilter) ->
+ %% Priority and Deadline not extracetd before. Do it now.
+ POverride = update_priority(NewDBRef, PrioFilter, Event, PO),
+ DeadL = update_deadline(NewDBRef, LifeFilter, Event, TS, DL),
+ StartT = update_starttime(NewDBRef, Event, ST),
+ do_add_event(NewDBRef, Event, TS, DeadL, StartT, POverride);
+%% Order Policy must be AnyOrder or PriorityOrder.
+write_event(_, {{_Prio, TS}, DL, ST, PO, Event}, _DBRef, NewDBRef,
+ _Key, LifeFilter, _PrioFilter) ->
+ DeadL = update_deadline(NewDBRef, LifeFilter, Event, TS, DL),
+ StartT = update_starttime(NewDBRef, Event, ST),
+ do_add_event(NewDBRef, Event, TS, DeadL, StartT, PO);
+write_event(_, {{_Prio, TS, DL}, DL, ST, PO, Event}, _DBRef, NewDBRef, _Key, _, _) ->
+ %% Both Deadline and Priority have been extracetd before.
+ StartT = update_starttime(NewDBRef, Event, ST),
+ do_add_event(NewDBRef, Event, TS, DL, StartT, PO).
+
+
+%%------------------------------------------------------------
+%% function : update_priority
+%% Arguments:
+%% Returns :
+%% Comment : The purpose with this function is to avoid
+%% calling MappingFilter priority again, especially
+%% deadline again (we especially want to avoid calling
+%% since it may require intra-ORB communication.
+%% Use only when doing an update.
+%%------------------------------------------------------------
+update_priority(DBRef, PrioFilter, Event, OldPrio) when is_atom(OldPrio) ->
+ get_prio_mapping_value(DBRef, PrioFilter, Event);
+update_priority(_DBRef, _PrioFilter, _Event, OldPrio) ->
+ OldPrio.
+
+%%------------------------------------------------------------
+%% function : update_deadline
+%% Arguments:
+%% Returns :
+%% Comment : The purpose with this function is to avoid
+%% calling MappingFilter or parsing the events for
+%% deadline again (we especially want to avoid calling
+%% the MappingFilter since it may require intra-ORB
+%% communication. Use only when doing an update.
+%%------------------------------------------------------------
+update_deadline(DBRef, _LifeFilter, _Event, _TS, _OldDeadL) when
+ ?get_DiscardP(DBRef) =/= ?not_DeadlineOrder,
+ ?get_OrderP(DBRef) =/= ?not_DeadlineOrder,
+ ?is_StopTNotSupported(DBRef) ->
+ %% We do not need to extract the Deadline since it will not be used.
+ false;
+update_deadline(DBRef, LifeFilter, Event, TS, OldDeadL) when is_atom(OldDeadL) ->
+ %% We need the Deadline and it have not been extracetd before.
+ DOverride = get_life_mapping_value(DBRef, LifeFilter, Event),
+ %% We must find out when the event was delivered; setting a deadline using
+ %% a new timestamp would not be accurate since we cannot tell for how long
+ %% the event have been waiting.
+ OldNow = convert_FIFO_Key(TS),
+ extract_deadline(Event, ?get_DefStopT(DBRef), ?get_StopTsupport(DBRef),
+ ?get_TimeRef(DBRef), DOverride, OldNow);
+update_deadline(_DBRef, _LifeFilter, _Event, _TS, OldDeadL) ->
+ %% We need the Deadline and it have been extracetd before.
+ OldDeadL.
+
+%%------------------------------------------------------------
+%% function : update_starttime
+%% Arguments:
+%% Returns :
+%% Comment : The purpose with this function is to avoid
+%% parsing the events for starttime again.
+%% Use only when doing an update.
+%%------------------------------------------------------------
+update_starttime(DBRef, Event, OldStartT) when is_atom(OldStartT) ->
+ %% Probably not previously extracted; try to get it.
+ extract_start_time(Event, ?get_StartTsupport(DBRef), ?get_TimeRef(DBRef));
+update_starttime(_DBRef, _Event, OldStartT) ->
+ %% Previously extracted.
+ OldStartT.
+
+%%------------------------------------------------------------
+%% function : discard_events
+%% Arguments: DBRef
+%% N - number of events we must discard.
+%% Returns :
+%% Comment : As default we shall Reject New Events when the limit
+%% is reached. Any discard order will do the same.
+%%
+%% This function can only be used for the discard policies
+%% Fifo, Priority and Deadline. Any or RejectNewEvents
+%% will not allow events to be stored at all, i.e., no events
+%% to discard. Lifo will not be stored either since when
+%% trying to add an event it is definitely the last event in.
+%%------------------------------------------------------------
+%% Since no Discard DB must the same Order policy.
+discard_events(#dbRef{orderRef = ORef, discardRef = undefined,
+ discardPolicy = ?not_DeadlineOrder}, N) ->
+ ?debug_print("Discarding ~p events Deadline Order.",[N]),
+ index_loop_backward(ets:last(ORef), undefined, ORef, N);
+discard_events(#dbRef{orderRef = ORef, discardRef = DRef,
+ discardPolicy = ?not_DeadlineOrder}, N) ->
+ ?debug_print("Discarding ~p events Deadline Order.",[N]),
+ index_loop_backward(ets:last(DRef), DRef, ORef, N);
+%% Fifo.
+discard_events(#dbRef{orderRef = ORef, discardRef = undefined,
+ discardPolicy = ?not_FifoOrder}, N) ->
+ ?debug_print("Discarding ~p events Fifo Order.",[N]),
+ index_loop_backward(ets:last(ORef), undefined, ORef, N);
+discard_events(#dbRef{orderRef = ORef, discardRef = DRef,
+ discardPolicy = ?not_FifoOrder}, N) ->
+ ?debug_print("Discarding ~p events Fifo Order.",[N]),
+ index_loop_backward(ets:last(DRef), DRef, ORef, N);
+%% Lifo- or Priority-Order
+discard_events(#dbRef{orderRef = ORef, discardRef = undefined}, N) ->
+ ?debug_print("Discarding ~p events Lifo- or Priority-Order.",[N]),
+ index_loop_forward(ets:first(ORef), undefined, ORef, N);
+discard_events(#dbRef{orderRef = ORef, discardRef = DRef}, N) ->
+ ?debug_print("Discarding ~p events Lifo- or Priority-Order.",[N]),
+ index_loop_forward(ets:first(DRef), DRef, ORef, N).
+
+
+index_loop_forward('$end_of_table', _, _, _Left) ->
+ ok;
+index_loop_forward(_, _, _, 0) ->
+ ok;
+index_loop_forward(Key, undefined, ORef, Left) ->
+ ets:delete(ORef, Key),
+ NewKey=ets:next(ORef, Key),
+ index_loop_forward(NewKey, undefined, ORef, Left-1);
+
+index_loop_forward({Key1, Key2, Key3}, DRef, ORef, Left) ->
+ ets:delete(DRef, {Key1, Key2, Key3}),
+ ets:delete(ORef, {Key3, Key2, Key1}),
+ NewKey=ets:next(DRef, {Key1, Key2, Key3}),
+ index_loop_forward(NewKey, DRef, ORef, Left-1);
+
+index_loop_forward({Key1, Key2}, DRef, ORef, Left) ->
+ ets:delete(DRef, {Key1, Key2}),
+ ets:delete(ORef, {Key2, Key1}),
+ NewKey=ets:next(DRef, {Key1, Key2}),
+ index_loop_forward(NewKey, DRef, ORef, Left-1).
+
+index_loop_backward('$end_of_table', _, _, _) ->
+ ok;
+index_loop_backward(_, _, _, 0) ->
+ ok;
+index_loop_backward(Key, undefined, ORef, Left) ->
+ ets:delete(ORef, Key),
+ NewKey=ets:prev(ORef, Key),
+ index_loop_backward(NewKey, undefined, ORef, Left-1);
+index_loop_backward({Key1, Key2}, DRef, ORef, Left) ->
+ ets:delete(DRef, {Key1, Key2}),
+ ets:delete(ORef, {Key2, Key1}),
+ NewKey=ets:prev(DRef, {Key1, Key2}),
+ index_loop_backward(NewKey, DRef, ORef, Left-1);
+index_loop_backward({Key1, Key2, Key3}, DRef, ORef, Left) ->
+ ets:delete(DRef, {Key1, Key2, Key3}),
+ ets:delete(ORef, {Key3, Key2, Key1}),
+ NewKey=ets:prev(DRef, {Key1, Key2, Key3}),
+ index_loop_backward(NewKey, DRef, ORef, Left-1).
+
+%%------------------------------------------------------------
+%% function : add_and_get_event
+%% Arguments: DBRef and Event
+%% Returns : {[], bool()} | {Event, bool()}
+%% Comment : This function is a mixture of ad anf get events.
+%% The intended use to avoid storing an event when
+%% not necessary.
+%%------------------------------------------------------------
+add_and_get_event(DBRef, Event) ->
+ add_and_get_event(DBRef, Event, undefined, undefined, true).
+
+add_and_get_event(DBRef, Event, Delete) ->
+ add_and_get_event(DBRef, Event, undefined, undefined, Delete).
+
+add_and_get_event(DBRef, Event, LifeFilter, PrioFilter) ->
+ add_and_get_event(DBRef, Event, LifeFilter, PrioFilter, true).
+
+add_and_get_event(DBRef, Event, LifeFilter, PrioFilter, Delete) ->
+ case ets:info(?get_OrderRef(DBRef), size) of
+ 0 when ?is_StartTNotSupported(DBRef), ?is_StopTNotSupported(DBRef),
+ Delete == true ->
+ %% No stored events and no timeouts used; just return the event.
+ {Event, false};
+ 0 when ?is_StartTNotSupported(DBRef), ?is_StopTNotSupported(DBRef) ->
+ %% No stored events and no timeouts used; just return the event.
+ {Event, false, []};
+ 0 when ?is_StartTNotSupported(DBRef) ->
+ %% Only deadline supported, lookup values and cehck if ok.
+ DOverride = get_life_mapping_value(DBRef, LifeFilter, Event),
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef), ?get_TimeRef(DBRef),
+ DOverride),
+ case check_deadline(DL) of
+ true when Delete == true ->
+ %% Expired, just discard the event.
+ {[], false};
+ true ->
+ {[], false, []};
+ _ when Delete == true ->
+ %% Not expired, we can safely return the event.
+ {Event, false};
+ _ ->
+ %% Not expired, we can safely return the event.
+ {Event, false, []}
+ end;
+ 0 when ?is_StopTNotSupported(DBRef) ->
+ %% Only starttime allowed, test if we can deliver the event now.
+ ST = extract_start_time(Event, ?get_StartTsupport(DBRef),
+ ?get_TimeRef(DBRef)),
+ case check_start_time(ST) of
+ false when Delete == true ->
+ DOverride = get_life_mapping_value(DBRef, LifeFilter, Event),
+ POverride = get_prio_mapping_value(DBRef, PrioFilter, Event),
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef),
+ ?get_TimeRef(DBRef), DOverride),
+ do_add_event(DBRef, Event, create_FIFO_Key(), DL, ST, POverride),
+ {[], true};
+ false ->
+ DOverride = get_life_mapping_value(DBRef, LifeFilter, Event),
+ POverride = get_prio_mapping_value(DBRef, PrioFilter, Event),
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef),
+ ?get_TimeRef(DBRef), DOverride),
+ do_add_event(DBRef, Event, create_FIFO_Key(), DL, ST, POverride),
+ {[], true, []};
+ _ when Delete == true ->
+ %% Starttime ok, just return the event.
+ {Event, false};
+ _ ->
+ %% Starttime ok, just return the event.
+ {Event, false, []}
+ end;
+ _->
+ %% Event already stored, just have to accept the overhead.
+ ST = extract_start_time(Event, ?get_StartTsupport(DBRef),
+ ?get_TimeRef(DBRef)),
+ DOverride = get_life_mapping_value(DBRef, LifeFilter, Event),
+ POverride = get_prio_mapping_value(DBRef, PrioFilter, Event),
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef),
+ ?get_TimeRef(DBRef), DOverride),
+ do_add_event(DBRef, Event, create_FIFO_Key(), DL, ST, POverride),
+ get_event(DBRef, Delete)
+ end.
+
+%%------------------------------------------------------------
+%% function : add_event
+%% Arguments: DBRef and Event
+%% Returns : true (or whatever 'ets:insert' returns) |
+%% {'EXCEPTION', #'IMP_LIMIT'{}}
+%% Comment : As default we shall deliver Events in Priority order.
+%% Hence, if AnyOrder set we will still deliver in
+%% Priority order. But we cannot use only the Priority
+%% value since if "all" events have the same priority
+%% there is a risk that some never will be delivered if
+%% the EventDB always contain events.
+%%
+%% When discard and order policy is equal we only use one
+%% DB since all we have to do is to "read from the other
+%% end" to discard the correct event(s).
+%%
+%% In the discard DB we must also store keys necessary to
+%% lookup the event in the order DB.
+%%
+%% If event limit reached 'IMPL_LIMIT' is raised if
+%% the discard policy is RejectNewEvents or AnyOrder.
+%% Theses two policies we currently define to be equal.
+%%------------------------------------------------------------
+
+add_event(DBRef, Event) ->
+ %% Save overhead by first checking if we really need to extract
+ %% Deadline and/or Priority.
+ Deadline = get_life_mapping_value(DBRef, undefined, Event),
+ Priority = get_prio_mapping_value(DBRef, undefined, Event),
+ add_event_helper(DBRef, Event, Deadline, Priority).
+
+add_event(DBRef, Event, LifeFilter, PrioFilter) ->
+ %% Save overhead by first checking if we really need to extract
+ %% Deadline and/or Priority.
+ Deadline = get_life_mapping_value(DBRef, LifeFilter, Event),
+ Priority = get_prio_mapping_value(DBRef, PrioFilter, Event),
+ add_event_helper(DBRef, Event, Deadline, Priority).
+
+add_event_helper(DBRef, Event, DOverride, POverride) ->
+ case ets:info(?get_OrderRef(DBRef), size) of
+ N when N < ?get_MaxEvents(DBRef), N > ?get_GCLimit(DBRef) ->
+ gc_events(DBRef, low),
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef), ?get_TimeRef(DBRef),
+ DOverride),
+ case check_deadline(DL) of
+ true ->
+ true;
+ _ ->
+ ST = extract_start_time(Event, ?get_StartTsupport(DBRef),
+ ?get_TimeRef(DBRef)),
+ do_add_event(DBRef, Event, create_FIFO_Key(), DL, ST, POverride)
+ end;
+ N when N < ?get_MaxEvents(DBRef) ->
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef), ?get_TimeRef(DBRef),
+ DOverride),
+ case check_deadline(DL) of
+ true ->
+ true;
+ _ ->
+ ST = extract_start_time(Event, ?get_StartTsupport(DBRef),
+ ?get_TimeRef(DBRef)),
+ do_add_event(DBRef, Event, create_FIFO_Key(), DL, ST, POverride)
+ end;
+ _N when ?get_DiscardP(DBRef) == ?not_RejectNewEvents ->
+ gc_events(DBRef, low),
+ corba:raise(#'IMP_LIMIT'{completion_status=?COMPLETED_NO});
+ _N when ?get_DiscardP(DBRef) == ?not_AnyOrder ->
+ gc_events(DBRef, low),
+ corba:raise(#'IMP_LIMIT'{completion_status=?COMPLETED_NO});
+ _N when ?get_DiscardP(DBRef) == ?not_LifoOrder ->
+ gc_events(DBRef, low),
+ corba:raise(#'IMP_LIMIT'{completion_status=?COMPLETED_NO});
+ _N ->
+ gc_events(DBRef, low),
+ %% Other discard policy; we must first store the event
+ %% and the look up in the Discard DB which event we
+ %% should remove.
+ DL = extract_deadline(Event, ?get_DefStopT(DBRef),
+ ?get_StopTsupport(DBRef), ?get_TimeRef(DBRef),
+ DOverride),
+ case check_deadline(DL) of
+ true ->
+ true;
+ _ ->
+ ST = extract_start_time(Event, ?get_StartTsupport(DBRef),
+ ?get_TimeRef(DBRef)),
+ do_add_event(DBRef, Event, create_FIFO_Key(), DL, ST, POverride),
+ discard_events(DBRef, 1)
+ end
+ end.
+
+
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_DeadlineOrder,
+ discardRef = DRef, discardPolicy = ?not_PriorityOrder,
+ defPriority = DefPrio, defStopT = _DefStopT}, Event, Key, DL, ST, PO) ->
+ Prio = extract_priority(Event, DefPrio, PO),
+ ets:insert(ORef, {{DL, Key, Prio}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{Prio, Key, DL}});
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_DeadlineOrder,
+ discardRef = DRef, discardPolicy = ?not_FifoOrder,
+ defStopT = _DefStopT}, Event, Key, DL, ST, PO) ->
+ ets:insert(ORef, {{DL, Key}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{Key, DL}});
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_DeadlineOrder,
+ discardRef = DRef, discardPolicy = ?not_LifoOrder,
+ defStopT = _DefStopT}, Event, Key, DL, ST, PO) ->
+ ets:insert(ORef, {{DL, Key}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{Key, DL}});
+%% Either the same (DeadlineOrder), RejectNewEvents or AnyOrder. No need
+%% to store anything in the discard policy, i.e., if the same we'll just
+%% read "from the other end" and AnyOrder and RejectNewEvents is equal.
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_DeadlineOrder,
+ defStopT = _DefStopT}, Event, Key, DL, ST, PO) ->
+ ets:insert(ORef, {{DL, Key}, DL, ST, PO, Event});
+
+
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_FifoOrder,
+ discardRef = DRef, discardPolicy = ?not_DeadlineOrder,
+ defStopT = _DefStopT}, Event, Key, DL, ST, PO) ->
+ ets:insert(ORef, {{Key, DL}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{DL, Key}});
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_FifoOrder,
+ discardRef = DRef, discardPolicy = ?not_PriorityOrder,
+ defPriority = DefPrio}, Event, Key, DL, ST, PO) ->
+ Prio = extract_priority(Event, DefPrio, PO),
+ ets:insert(ORef, {{Key, Prio}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{Prio, Key}});
+%% The discard policy must RejectNewEvents, AnyOrder, Fifo or Lifo order.
+do_add_event(#dbRef{orderRef = ORef, orderPolicy = ?not_FifoOrder,
+ discardRef = _DRef}, Event, Key, DL, ST, PO) ->
+ ets:insert(ORef, {Key, DL, ST, PO, Event});
+
+%% Order Policy must be AnyOrder or PriorityOrder.
+do_add_event(#dbRef{orderRef = ORef,
+ discardRef = DRef, discardPolicy = ?not_DeadlineOrder,
+ defPriority = DefPrio, defStopT = _DefStopT}, Event, Key, DL, ST, PO) ->
+ Prio = extract_priority(Event, DefPrio, PO),
+ ets:insert(ORef, {{Prio, Key, DL}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{DL, Key, Prio}});
+do_add_event(#dbRef{orderRef = ORef,
+ discardRef = DRef, discardPolicy = ?not_FifoOrder,
+ defPriority = DefPrio}, Event, Key, DL, ST, PO) ->
+ Prio = extract_priority(Event, DefPrio, PO),
+ ets:insert(ORef, {{Prio, Key}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{Key, Prio}});
+
+do_add_event(#dbRef{orderRef = ORef,
+ discardRef = DRef, discardPolicy = ?not_LifoOrder,
+ defPriority = DefPrio}, Event, Key, DL, ST, PO) ->
+ Prio = extract_priority(Event, DefPrio, PO),
+ ets:insert(ORef, {{Prio, Key}, DL, ST, PO, Event}),
+ ets:insert(DRef, {{Key, Prio}});
+
+%% Order Policy must be AnyOrder or PriorityOrder and Discard Policy must be
+%% AnyOrder or RejectNewEvents
+do_add_event(#dbRef{orderRef = ORef, defPriority = DefPrio}, Event, Key, DL, ST, PO) ->
+ Prio = extract_priority(Event, DefPrio, PO),
+ ets:insert(ORef, {{Prio, Key}, DL, ST, PO, Event}).
+
+%%------------------------------------------------------------
+%% function : destroy_db
+%% Arguments: A DB reference
+%% Returns :
+%%------------------------------------------------------------
+destroy_db(#dbRef{orderRef = ORef, discardRef = undefined}) ->
+ ets:delete(ORef);
+destroy_db(#dbRef{orderRef = ORef, discardRef = DRef}) ->
+ ets:delete(ORef),
+ ets:delete(DRef).
+
+%%------------------------------------------------------------
+%% function : destroy_discard_db
+%% Arguments: A DB reference
+%% Returns :
+%%------------------------------------------------------------
+destroy_discard_db(#dbRef{discardRef = undefined}) ->
+ ok;
+destroy_discard_db(#dbRef{discardRef = DRef}) ->
+ ets:delete(DRef).
+
+%%------------------------------------------------------------
+%% function : destroy_order_db
+%% Arguments: A DB reference
+%% Returns :
+%%------------------------------------------------------------
+destroy_order_db(#dbRef{orderRef = ORef}) ->
+ ets:delete(ORef).
+
+%%------------------------------------------------------------
+%% function : create_db
+%% Arguments: QoS (local representation).
+%% Returns : A DB reference
+%%------------------------------------------------------------
+create_db(QoS, GCTime, GCLimit, TimeRef) ->
+ DiscardRef =
+ case {?not_GetDiscardPolicy(QoS), ?not_GetOrderPolicy(QoS)} of
+ {Equal, Equal} ->
+ undefined;
+ {?not_PriorityOrder, ?not_AnyOrder} ->
+ %% NOTE: Any- and Priority-Order delivery policy is equal.
+ undefined;
+ {?not_RejectNewEvents, _} ->
+ undefined;
+ {?not_AnyOrder, _} ->
+ undefined;
+ {?not_LifoOrder, ?not_FifoOrder} ->
+ undefined;
+ _ ->
+ ets:new(oe_ets, [set, public, ordered_set])
+ end,
+ DBRef = ?CreateRef(ets:new(oe_ets, [set, public, ordered_set]),
+ DiscardRef,
+ ?not_GetOrderPolicy(QoS), ?not_GetDiscardPolicy(QoS),
+ ?not_GetPriority(QoS), ?not_GetMaxEventsPerConsumer(QoS),
+ ?not_GetTimeout(QoS), ?not_GetStartTimeSupported(QoS),
+ ?not_GetStopTimeSupported(QoS), GCTime, GCLimit, TimeRef),
+ if
+ ?is_TimeoutNotUsed(DBRef), ?is_StopTNotSupported(DBRef) ->
+ ok;
+ true ->
+ {M,S,U} = now(),
+ put(oe_GC_timestamp, {M,S+GCTime,U})
+ end,
+ DBRef.
+
+%%------------------------------------------------------------
+%% function : get_prio_mapping_value
+%% Arguments: A MappingFilter reference | undefined
+%% Event (Any or Structured)
+%% Returns : undefined | Data
+%%------------------------------------------------------------
+get_prio_mapping_value(DBRef, _, _) when ?get_DiscardP(DBRef) =/= ?not_PriorityOrder,
+ ?get_OrderP(DBRef) =/= ?not_AnyOrder,
+ ?get_OrderP(DBRef) =/= ?not_PriorityOrder ->
+ false;
+get_prio_mapping_value(_, undefined, _) ->
+ undefined;
+get_prio_mapping_value(_, MFilter, Event) when is_record(Event, 'any') ->
+ case catch 'CosNotifyFilter_MappingFilter':match(MFilter, Event) of
+ {false, DefVal} when is_record(DefVal, 'any') ->
+ any:get_value(DefVal);
+ {true, Matched} when is_record(Matched, 'any') ->
+ any:get_value(Matched);
+ _ ->
+ undefined
+ end;
+get_prio_mapping_value(_, MFilter, Event) ->
+ case catch 'CosNotifyFilter_MappingFilter':match_structured(MFilter, Event) of
+ {false, DefVal} when is_record(DefVal, 'any') ->
+ any:get_value(DefVal);
+ {true, Matched} when is_record(Matched, 'any') ->
+ any:get_value(Matched);
+ _ ->
+ undefined
+ end.
+
+%%------------------------------------------------------------
+%% function : get_life_mapping_value
+%% Arguments: A MappingFilter reference | undefined
+%% Event (Any or Structured)
+%% Returns : undefined | Data
+%%------------------------------------------------------------
+get_life_mapping_value(DBRef, _, _) when ?get_DiscardP(DBRef) =/= ?not_DeadlineOrder,
+ ?get_OrderP(DBRef) =/= ?not_DeadlineOrder,
+ ?is_StopTNotSupported(DBRef) ->
+ false;
+get_life_mapping_value(_, undefined, _) ->
+ undefined;
+get_life_mapping_value(_, MFilter, Event) when is_record(Event, 'any') ->
+ case catch 'CosNotifyFilter_MappingFilter':match(MFilter, Event) of
+ {false, DefVal} when is_record(DefVal, 'any') ->
+ any:get_value(DefVal);
+ {true, Matched} when is_record(Matched, 'any') ->
+ any:get_value(Matched);
+ _ ->
+ undefined
+ end;
+get_life_mapping_value(_, MFilter, Event) ->
+ case catch 'CosNotifyFilter_MappingFilter':match_structured(MFilter, Event) of
+ {false, DefVal} when is_record(DefVal, 'any') ->
+ any:get_value(DefVal);
+ {true, Matched} when is_record(Matched, 'any') ->
+ any:get_value(Matched);
+ _ ->
+ undefined
+ end.
+
+%%------------------------------------------------------------
+%% function : validate_event
+%% Arguments: Subscribe data
+%% A sequence of Events, 'structured' or an 'any' record
+%% A list of filter references
+%% Status, i.e., do we have to filter the events or just check subscr.
+%% Returns : A tuple of two lists; list1 the events that passed
+%% and list2 the events that didn't pass.
+%%------------------------------------------------------------
+validate_event(true, Events, Filters, _, 'MATCH') ->
+ filter_events(Events, Filters, false);
+validate_event(true, Events, _Filters, _, _) ->
+ {Events, []};
+validate_event({_Which, _WC}, Event, Filters, _, 'MATCH') when is_record(Event, any) ->
+ filter_events(Event, Filters, false);
+validate_event({_Which, _WC}, Event, _Filters, _, _) when is_record(Event, any) ->
+ {Event, []};
+validate_event({Which, WC}, Events, Filters, DBRef, 'MATCH') ->
+ Passed=validate_event2(DBRef, Events, Which, WC, []),
+ filter_events(Passed, Filters, true);
+validate_event({Which, WC}, Events, _Filters, DBRef, _) ->
+ Passed=validate_event2(DBRef, Events, Which, WC, []),
+ {lists:reverse(Passed), []}.
+
+validate_event2(_, [], _, _, []) ->
+ [];
+validate_event2(_, [], _, _, Acc) ->
+ Acc;
+validate_event2(DBRef, [Event|T], Which, WC, Acc) ->
+ ET = ((Event#'CosNotification_StructuredEvent'.header)
+ #'CosNotification_EventHeader'.fixed_header)
+ #'CosNotification_FixedEventHeader'.event_type,
+ CheckList =
+ case Which of
+ both ->
+ [ET];
+ domain ->
+ [ET,
+ ET#'CosNotification_EventType'{type_name=""},
+ ET#'CosNotification_EventType'{type_name="*"}];
+ type ->
+ [ET,
+ ET#'CosNotification_EventType'{domain_name=""},
+ ET#'CosNotification_EventType'{domain_name="*"}];
+ _ ->
+ [ET,
+ ET#'CosNotification_EventType'{type_name=""},
+ ET#'CosNotification_EventType'{type_name="*"},
+ ET#'CosNotification_EventType'{domain_name=""},
+ ET#'CosNotification_EventType'{domain_name="*"}]
+ end,
+ case check_subscription(DBRef, CheckList) of
+ true ->
+ validate_event2(DBRef, T, Which, WC, [Event|Acc]);
+ _->
+ case catch cosNotification_Filter:match_types(
+ ET#'CosNotification_EventType'.domain_name,
+ ET#'CosNotification_EventType'.type_name,
+ WC) of
+ true ->
+ validate_event2(DBRef, T, Which, WC, [Event|Acc]);
+ _->
+ validate_event2(DBRef, T, Which, WC, Acc)
+ end
+ end.
+
+check_subscription(_, []) ->
+ false;
+check_subscription(DBRef, [H|T]) ->
+ case ets:lookup(DBRef, H) of
+ [] ->
+ check_subscription(DBRef, T);
+ _ ->
+ true
+ end.
+
+
+%%------------------------------------------------------------
+%% function : filter_events
+%% Arguments: A sequence of structured Events or #any
+%% Returns : A tuple of two lists; list1 the events that passed
+%% and list2 the events that didn't pass.
+%%------------------------------------------------------------
+
+filter_events(Events, []) ->
+ {Events, []};
+filter_events(Events, Filters) ->
+ filter_events(Events, Filters, [], [], false).
+
+filter_events(Events, [], false) ->
+ {Events, []};
+filter_events(Events, [], _) ->
+ {lists:reverse(Events), []};
+filter_events(Events, Filters, Reversed) ->
+ filter_events(Events, Filters, [], [], Reversed).
+
+filter_events([], _, AccPassed, AccFailed, false) ->
+ {lists:reverse(AccPassed), lists:reverse(AccFailed)};
+filter_events([], _, AccPassed, AccFailed, _) ->
+ {AccPassed, AccFailed};
+filter_events([H|T], Filters, AccPassed, AccFailed, Reversed) ->
+ case call_filters(Filters, H) of
+ true ->
+ filter_events(T, Filters, [H|AccPassed], AccFailed, Reversed);
+ _ ->
+ filter_events(T, Filters, AccPassed, [H|AccFailed], Reversed)
+ end;
+filter_events(Any, Filters, _AccPassed, _AccFailed, _Reversed) ->
+ case call_filters(Filters, Any) of
+ true ->
+ {Any, []};
+ _ ->
+ {[], Any}
+ end.
+
+call_filters([], _) ->
+ false;
+call_filters([{_,H}|T], Event) when is_record(Event, any) ->
+ case catch 'CosNotifyFilter_Filter':match(H, Event) of
+ true ->
+ true;
+ _->
+ call_filters(T, Event)
+ end;
+call_filters([{_,H}|T], Event) when ?not_isConvertedAny(Event) ->
+ case catch 'CosNotifyFilter_Filter':match(H,
+ Event#'CosNotification_StructuredEvent'.remainder_of_body) of
+ true ->
+ true;
+ _->
+ call_filters(T, Event)
+ end;
+call_filters([{_,H}|T], Event) ->
+ case catch 'CosNotifyFilter_Filter':match_structured(H, Event) of
+ true ->
+ true;
+ _->
+ call_filters(T, Event)
+ end.
+
+
+%%--------------- END OF MODULE ------------------------------
diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk
new file mode 100644
index 0000000000..65f9812f31
--- /dev/null
+++ b/lib/cosNotification/vsn.mk
@@ -0,0 +1,11 @@
+COSNOTIFICATION_VSN = 1.1.12
+
+TICKETS = OTP-8201
+
+TICKETS_1.1.11 = OTP-7987
+
+TICKETS_1.1.10 = OTP-7837
+
+TICKETS_1.1.9 = OTP-7595
+
+TICKETS_1.1.8 = OTP-7553