text:
Chapter 7
JAPE: Regular Expressions Over Annotations [#]
If Osama bin Laden did not exist, it would be necessary to invent him. For the past four years, his name has been invoked whenever a US president has sought to increase the defence budget or wriggle out of arms control treaties. He has been used to justify even President Bush's missile defence programme, though neither he nor his associates are known to possess anything approaching ballistic missile technology. Now he has become the personification of evil required to launch a crusade for good: the face behind the faceless terror.
The closer you look, the weaker the case against Bin Laden becomes. While the terrorists who inflicted Tuesday's dreadful wound may have been inspired by him, there is, as yet, no evidence that they were instructed by him. Bin Laden's presumed guilt appears to rest on the supposition that he is the sort of man who would have done it. But his culpability is irrelevant: his usefulness to western governments lies in his power to terrify. When billions of pounds of military spending are at stake, rogue states and terrorist warlords become assets precisely because they are liabilities.
The need for dissent, George Monbiot, The Guardian, Tuesday September 18, 2001.
This chapter describes JAPE – a Java Annotation Patterns Engine. JAPE provides finite state transduction over annotations based on regular expressions. JAPE is a version of CPSL – Common Pattern Specification Language1.
JAPE allows you to recognise regular expressions in annotations on documents. Hang on, there's something wrong here: a regular language can only describe sets of strings, not graphs, and GATE's model of annotations is based on graphs. Hmmm. Another way of saying this: typically, regular expressions are applied to character strings, a simple linear sequence of items, but here we are applying them to a much more complex data structure. The result is that in certain cases the matching process in non-deterministic (i.e. the results are dependent on random factors like the addresses at which data is stored in the virtual machine): when there is structure in the graph being matched that requires more than the power of a regular automaton to recognise, JAPE chooses an alternative arbitrarily. However, this is not the bad news that it seems to be, as it turns out that in many useful cases the data stored in annotation graphs in GATE (and other language processing systems) can be regarded as simple sequences, and matched deterministically with regular expressions.
A JAPE grammar consists of a set of phases, each of which consists of a set of pattern/action rules. The phases run sequentially and constitute a cascade of finite state transducers over annotations. The left-hand-side (LHS) of the rules consist of an annotation pattern that may contain regular expression operators (e.g. *, ?, +). The right-hand-side (RHS) consists of annotation manipulation statements. Annotations matched on the LHS of a rule may be referred to on the RHS by means of labels that are attached to pattern elements.
At the beginning of each grammar, several options can be set:
- Control - this defines the method of rule matching (see Section 7.3)
- Debug - when set to true, if the grammar is running in Appelt mode and there is more than one possible match, the conflicts will be displayed on the standard output. See also Section 7.5.
Input annotations must also be defined at the start of each grammar. If no annotations are defined, all annotations will be matched.
There are 3 main ways in which the pattern can be specified:
- specify a string of text, e.g. {Token.string == "of"}
- specify the presence or absence of an annotation previously assigned from a gazetteer, tokeniser, or other module, e.g. {Lookup} (matches a Lookup annotation) or {!Lookup} (matches if there is not a Lookup annotation at this location).
- specify the attributes (and values) of an annotation. Several operators are supported - see
section 7.1 for full details:
- {Token.kind == "number"}, {Token.length != 4} - equality and inequality.
- {Token.string > "aardvark"}, {Token.length < 10} - comparison operators. >= and <= are also supported.
- {Token.string =~ "[Dd]ogs"}, {Token.string !~ "(?i)hello"} - regular expression. ==~ and !=~ are also provided, for whole-string matching.
- {X contains Y} and {X within Y} for checking annotations within the context of other annotations.
Macros can also be used in the LHS of rules. This means that instead of expressing the information in the rule, it is specified in a macro, which can then be called in the rule. The reason for this is simply to avoid having to repeat the same information in several rules. Macros can themselves be used inside other macros.
New as of September 2008, in addition to referencing annotation features, JAPE allows access to other "meta-properties" of an annotation. This is done by using an "@" symbol rather than a "." symbol after the annotation type name. The three meta-properties that are built in are:
- length - returns the spanning length of the annotation.
- string - returns the string spanned by the annotation in the document.
- cleanString - Like string, but with extra white space stripped out. (i.e. "\s+" goes to a single space and leading or trailing white space is removed).
At this time, you cannot access the value of a "meta-property" from a non-java RHS of a rule. (e.g. You can't write: {X@length > "5"}:label-->:label.New = {somefeat = :label.X@length }. We hope to add this at some point.
The same union and kleen operators can be used as for the tokeniser rules, i.e.
New as of late-September 2008, a range notation can also be added. e.g.
matches one to three Tokens in a row.
({Token.kind == number})[3]
matches exactly 3 number Tokens in a row.
The pattern description is followed by a label for the annotation. A label is denoted by a preceding colon; in the example below, the label is :location.
The RHS of the rule contains information about the annotation. Information about the annotation is transferred from the LHS of the rule using the label just described, and annotated with the entity type (which follows it). Finally, attributes and their corresponding values are added to the annotation. Alternatively, the RHS of the rule can contain Java code to create or manipulate annotations.
In the simple example below, the pattern described will be awarded an annotation of type "Enamex" (because it is an entity name). This annotation will have the attribute "kind", with value "location", and the attribute "rule", with value "GazLocation". (The purpose of the "rule" attribute is simply to ease the process of manual rule validation).
Rule: GazLocation
{Lookup.majorType == location}
:location -->
:location.Enamex = {kind="location", rule=GazLocation}
It is also possible to have more than one pattern and corresponding action, as shown in the rule below. On the LHS, each pattern is enclosed in a set of round brackets and has a unique label; on the RHS, each lable is associated with an action. In this example, the Lookup annotation is labelled "jobtitle" and is given the new annotation JobTitle; the TempPerson annotation is labelled "person" and is given the new annotation "Person".
Rule: PersonJobTitle
Priority: 20
{Lookup.majorType == jobtitle}
:jobtitle.JobTitle = {rule = "PersonJobTitle"},
:person.Person = {kind = "personName", rule = "PersonJobTitle"}
Similarly, labelled patterns can be nested, as in the example below, where the whole pattern is annotated as Person, but within the pattern, the jobtitle is annotated as JobTitle.
Rule: PersonJobTitle2
Priority: 20
{Lookup.majorType == jobtitle}
:jobtitle.JobTitle = {rule = "PersonJobTitle"},
:person.Person = {kind = "personName", rule = "PersonJobTitle"}
JAPE provides limited support for copying annotation feature values from the left to the right hand side of a rule, for example:
Rule: LocationType
{Lookup.majorType == location}
:loc.Location = {rule = "LocationType", type = :loc.Lookup.minorType}
This will set the "type" feature of the generated location to the value of the "minorType" feature from the "Lookup" annotation bound to the loc label. If the Lookup has no minorType, the Location will have no "type" feature. The behaviour of newFeat = :bind.Type.oldFeat is:
- Find all the annotations of type Type from the left hand side binding bind.
- Find one of them that has a non-null value for its oldFeat feature (if there is more than one, which one is chosen is up to the JAPE implementation).
- If such a value exists, set the newFeat feature of our newly created annotation to this value.
- If no such non-null value exists, do not set the newFeat feature at all.
Notice that the behaviour is deliberately underspecified if there is more than one Type annotation in bind. If you need more control, or if you want to copy several feature values from the same left hand side annotation, you should consider using Java code on the right hand side of your rule (see section 7.7).
Grammar rules can essentially be of two types. The first type of rule involves no gazetteer lookup, but can be defined using a small set of possible formats. In general, these are fairly straightforward and offer little potential for ambiguity.
The second type of rules rely more heavily on the gazetteer lists, and cover a much wider range of possibilities. This not only means that many rules may be needed to describe all situations, but that there is a much greater potential for ambiguity. This leads to the necessity for rule ordering and prioritisation, as will be discussed below.
For example, a single rule is sufficient to identify an IP address, because there is only one basic format - a series of numbers, each set connected by a dot. The rule for this is given below2:
Rule: IPAddress
{Token.kind == number}
{Token.string == "."}
{Token.kind == number}
{Token.string == "."}
{Token.kind == number}
{Token.string == "."}
{Token.kind == number}
:ipAddress -->
:ipAddress.Address = {kind = "ipAddress"}
To identify a date or time, there are many possible variations, and so many rules are needed. For example, the same date information can appear in the following formats (amongst others):
Wed, 10/7/00
Wed, 10/July/00
Wed, 10 July, 2000
Wed 10th of July, 2000
Wed. July 10th, 2000
Wed 10 July 2000
Different types of date can also be expressed. For example, the following would also be classified as date entities:
the late '80s
St. Andrew's Day
from March to April
This also means there is a much greater potential for ambiguity. For example, many of the months of the year can also be girls' Christian names (e.g. May, June). This means that contextual information may be needed to disambiguate them, or we may have to guess which is more likely, based on frequency. For example, while "Friday" could be a person's name (as in "Man Friday"), it is much more likely to be a day of the week.
Finally, macros can also be used on the RHS of rules. In this case, the label (which matches the label on the LHS of the rule) should be included in the macro. Below we give an example of using a macro on the RHS.
Macro: UNDERSCORES_OKAY // separate
:match // lines
gate.AnnotationSet matchedAnns = (gate.AnnotationSet)bindings.get("match");
int begOffset = matchedAnns.firstNode().getOffset().intValue();
int endOffset = matchedAnns.lastNode().getOffset().intValue();
String mydocContent = doc.getContent().toString();
String matchedString = mydocContent.substring(begOffset, endOffset);
gate.FeatureMap newFeatures = Factory.newFeatureMap();
if(matchedString.equals("Spanish")) {
newFeatures.put("myrule", "Lower");
else {
newFeatures.put("myrule", "Upper");
newFeatures.put("quality", "1");
annotations.add(matchedAnns.firstNode(), matchedAnns.lastNode(),
"Spanish_mark", newFeatures);
Rule: Lower
({Token.string == "Spanish"})
:match)-->UNDERSCORES_OKAY // no label here, only macro name
Rule: Upper
({Token.string == "SPANISH"})
:match)-->UNDERSCORES_OKAY // no label here, only macro name
7.1 Matching operators in detail [#]
This section gives more detail on the behaviour of the matching operators used on the left-hand side of JAPE rules.
7.1.1 Equality operators ("==" and "!=")
The basic operator in JAPE is equality. {Lookup.majorType == "person"} matches a Lookup annotation whose majorType feature has the value "person". Similarly {Lookup.majorType != "person"} would match any Lookup whose majorType feature does not have the value "person". If a feature is missing it is treated as if it had an empty string as its value, so this would also match a Lookup annotation that did not have a majorType feature at all.
Certain type coercions are performed:
- If the constraint's attribute is a string, it is compared with the annotation feature value using string equality (String.equals()).
- If the constraint's attribute is an integer it is treated as a java.lang.Long. If the annotation feature value is also a Long, or is a string that can be parsed as a Long, then it is compared using Long.equals().
- If the constraint's attribute is a floating-point number it is treated as a java.lang.Double. If the annotation feature value is also a Double, or is a string that can be parsed as a Double, then it is compared using Double.equals().
- If the constraint's attribute is true or false (without quotes) it is treated as a java.lang.Boolean. If the annotation feature value is also a Boolean, or is a string that can be parsed as a Boolean, then it is compared using Boolean.equals().
The != operator matches exactly when == doesn't.
7.1.2 Comparison operators ("<", "<=", ">=" and ">")
Comparison operators have their expected meanings, for example {Token.length > 3} matches a Token annotation whose length attribute is an integer greater than 3. The behaviour of the operators depends on the type of the constraint's attribute:
- If the constraint's attribute is a string it is compared with the annotation feature value using Unicode-lexicographic order (see String.compareTo()).
- If the constraint's attribute is an integer it is treated as a java.lang.Long. If the annotation feature value is also a Long, or is a string that can be parsed as a Long, then it is compared using Long.compareTo().
- If the constraint's attribute is a floating-point number it is treated as a java.lang.Double. If the annotation feature value is also a Double, or is a string that can be parsed as a Double, then it is compared using Double.compareTo().
7.1.3 Regular expression operators ("=~", "==~", "!~" and "!=~") [#]
These operators match regular expressions. {Token.string =~ "[Dd]ogs"} matches a Token annotation whose string feature contains a substring that matches the regular expression [Dd]ogs, using !~ would match if the feature value does not contain a substring that matches the regular expression. The ==~ and !=~ operators are like =~ and !~ respectively, but require that the whole value match (or not match) the regular expression3. As with ==, missing features are treated as if they had the empty string as their value, so the constraint {Identifier.name ==~ "(?i)[aeiou]*"} would match an Identifier annotation which does not have a name feature, as well as any whose name contains only vowels.
The matching uses the standard Java regular expression library, so full details of the pattern syntax can be found in the JavaDoc documentation for java.util.regex.Pattern. There are a few specific points to note:
- To enable flags such as case-insensitive matching you can use the (?flags) notation. See the Pattern JavaDocs for details.
- If you need to include a double quote character in a regular expression you must precede it with a backslash, otherwise JAPE will give a syntax error. Quoted strings in JAPE grammars also convert the sequences \n, \r and \t to the characters newline (U+000A), carriage return (U+000D) and tab (U+0009) respectively, but these characters can match literally in regular expressions so it does not make any difference to the result in most cases.4
7.1.4 Contextual operators ("contains" and "within") [#]
These operators match annotations within the context of other annotations.
- contains - Written as {X contains Y}, returns true if an annotation of type X completely contains an annotation of type Y.
- within - Written as {X within Y}, returns true if an annotation of type X is completely covered by an annotation of type Y.
For either operator, the right-hand value (Y in the above examples) can be a full constraint itself. For example {X contains {Y.foo=bar}} is also accepted. The operators can be used in a multi-constraint statement just like any of the traditional ones, so {X.f1 != "something", X contains {Y.foo=bar}} is valid.
It is possible to add additional custom operators without modifying the JAPE language. There are new init-time parameters to Transducer so that additional annotation "meta-property" accessors and custom operators can be referenced at runtime. To add a custom operator, write a class that implements gate.jape.constraint.ConstraintPredicate, and then list that class name for the Transducer's "operators" property. Similarly, to add a custom "meta-property" accessor, write a class that implements gate.jape.constraint.AnnotationAccessor, and then list that class name in the Transducer's "annotationAccessors" property.
7.2 Use of Context
Context can be dealt with in the grammar rules in the following way. The pattern to be annotated is always enclosed by a set of round brackets. If preceding context is to be included in the rule, this is placed before this set of brackets. This context is described in exactly the same way as the pattern to be matched. If context following the pattern needs to be included, it is placed after the label given to the annotation. Context is used where a pattern should only be recognised if it occurs in a certain situation, but the context itself does not form part of the pattern to be annotated.
For example, the following rule for Time (assuming an appropriate macro for "year") would mean that a year would only be recognised if it occurs preceded by the words "in" or "by":
Rule: YearContext1
({Token.string == "in"}|
{Token.string == "by"}
:date -->
:date.Timex = {kind = "date", rule = "YearContext1"}
Similarly, the following rule (assuming an appropriate macro for "email") would mean that an email address would only be recognised if it occurred inside angled brackets (which would not themselves form part of the entity):
Rule: Emailaddress1
({Token.string == ''<''})
({Token.string == ''>''})
:email.Address= {kind = "email", rule = "Emailaddress1"}
Also, it is possible to specify the constraint that one annotation must start at the same place as another. For example:
Rule: SurnameStartingWithDe
{Token.string == "de",
Lookup.majorType == "name",
Lookup.minorType == "surname"}
:de.Surname = {prefix = "de"}
This rule would match anywhere where a Token with string "de" and a Lookup with majorType "name" and minorType "surname" start at the same offset in the text. Both the Lookup and Token annotations would be included in the :de binding, so the Surname annotation generated would span the longer of the two. Constraints on the same annotation type must be satisfied by a single annotation, so in this example there must be a single Lookup matching both the major and minor types – the rule would not match if there were two different lookups at the same location, one of them satisfying each constraint.
7.3 Use of Priority [#]
Each grammar has one of 5 possible control styles: "brill", "all", "first", "once" and "appelt". This is specified at the beginning of the grammar.
The Brill style means that when more than one rule matches the same region of the document, they are all fired. The result of this is that a segment of text could be allocated more than one entity type, and that no priority ordering is necessary. Brill will execute all matching rules starting from a given position and will advance and continue matching from the position in the document where the longest match finishes.
The "all" style is similar to Brill, in that it will also execute all matching rules, but the matching will continue from the next offset to the current one.
For example, where [] are annotations of type Ann
[aaa[bbb]] [ccc[ddd]]
then a rule matching {Ann} and creating {Ann-2} for the same spans will generate:
BRILL: [aaabbb] [cccddd]
ALL: [aaa[bbb]] [ccc[ddd]]
With the "first" style, a rule fires for the first match that's found. This makes it unappropiate for rules that end in "+" or "?" or "*". Once a match is found the rule is fired; it does not attempt to get a longer match (as the other two styles do).
With the "once" style, once a rule has fired, the whole JAPE phase exits after the first match.
With the appelt style, only one rule can be fired for the same region of text, according to a set of priority rules. Priority operates in the following way.
- From all the rules that match a region of the document starting at some point X, the one which matches the longest region is fired.
- If more than one rule matches the same region, the one with the highest priority is fired
- If there is more than one rule with the same priority, the one defined earlier in the grammar is fired.
An optional priority declaration is associated with each rule, which should be a positive integer. The higher the number, the greater the priority. By default (if the priority declaration is missing) all rules have the priority -1 (i.e. the lowest priority).
For example, the following two rules for location could potentially match the same text.
Rule: Location1
Priority: 25
({Lookup.majorType == loc_key, Lookup.minorType == pre}
{Lookup.majorType == location}
{Lookup.majorType == loc_key, Lookup.minorType == post})?
:locName -->
:locName.Location = {kind = "location", rule = "Location1"}
Rule: GazLocation
Priority: 20
({Lookup.majorType == location}):location
--> :location.Name = {kind = "location", rule=GazLocation}
Assume we have the text "China sea", that "China" is defined in the gazetteer as "location", and that sea is defined as a "loc_key" of type "post". In this case, rule Location1 would apply, because it matches a longer region of text starting at the same point ("China sea", as opposed to just "China"). Now assume we just have the text "China". In this case, both rules could be fired, but the priority for Location1 is highest, so it will take precedence. In this case, since both rules produce the same annotation, so it is not so important which rule is fired, but this is not always the case.
One important point of which to be aware is that prioritisation only operates within a single grammar. Although we could make priority global by having all the rules in a single grammar, this is not ideal due to other considerations. Instead, we currently combine all the rules for each entity type in a single grammar. An index file (main.jape) is used to define which grammars should be used, and in which order they should be fired.
7.4 Use of negation [#]
All the examples in the preceding sections involve constraints that require the presence of certain annotations to match. JAPE also supports "negative" constraints which specify the absence of annotations. A negative constraint is signalled in the grammar by a "!" character.
Negative constraints are generally used in combination with positive ones to constrain the locations at which the positive constraint can match. For example:
Rule: PossibleName
{Token.orth == "upperInitial", !Lookup}
:name.PossibleName = {}
This rule would match any uppercase-initial Token, but only where there is no Lookup annotation starting at the same location. The general rule is that a negative constraint matches at any location where the corresponding positive constraint would not match. Negative constraints do not contribute any annotations to the bindings - in the example above, the :name binding would contain only the Token annotation. The exception to this is when a negative constraint is used alone, without any positive constraints in the combination. In this case it binds all the annotations at the match position that do not match the constraint. Thus, {!Lookup} would bind all the annotations starting at this location except Lookups. In most cases, negative constraints should only be used in combination with positive ones.
Any constraint can be negated, for example:
Rule: SurnameNotStartingWithDe
{Surname, !Token.string ==~ "[Dd]e"}
:name.NotDe = {}
This would match any Surname annotation that does not start at the same place as a Token with the string "de" or "De". Note that this is subtly different from {Surname, Token.string !=~ "[Dd]e"}, as the second form requires a Token annotation to be present, whereas the first form (!Token...) will match if there is no Token annotation at all at this location.5
7.5 Useful tricks [#]
Although the JAPE language has some limitations as to how rules and patterns can be expressed, there are some useful tricks to overcome these problems.
- Using priority to resolve ambiguity. If the Appelt style of matching is selected, rule priority
operates in the following way.
- Length of rule – a rule matching a longer pattern will fire first.
- Explicit priority declaration. Use the optional Priority function to assign a ranking. The higher the number, the higher the priority. If no priority is stated, the default is -1.
- Order of rules. In the case where the above two factors do not distinguish between two rules, the order in which the rules are stated applies. Rules stated first have higher priority.
Because priority can only operate within a single grammar, this can be a problem for dealing with ambiguity issues. One solution to this is to create a temporary set of annotations in initial grammars, and then manipulate this temporary set in one or more later phases (for example, by converting temporary annotations from different phases into permanent annotations in a single final phase). See the default set of grammars for an example of this.
- Negative operator. JAPE provides an operator to look for the absence of a single annotation
type (see section 7.4), but there is no support for a general negative operator to
prevent a rule from firing if a particular sequence of annotations is found. One
solution to this is to create a "negative rule" which has higher priority than the
matching "positive rule". The style of matching must be Appelt for this to work.
To create a negative rule, simply state on the LHS of the rule the pattern that
should NOT be matched, and on the RHS do nothing. In this way, the positive rule
cannot be fired if the negative pattern matches, and vice versa, which has the
same end result as using a negative operator. A useful variation for developers is
to create a dummy annotation on the RHS of the negative rule, rather than to
do nothing, and to give the dummy annotation a rule feature. In this way, it is
obvious that the negative rule has fired. Alternatively, use Java code on the RHS
to print a message when the rule fires. An example of a matching negative and
positive rule follows. Here, we want a rule which matches a surname followed by a
comma and a set of initials. But we want to specify that the initials shouldn't have
the POS category PRP (personal pronoun). So we specify a negative rule that
will fire if the PRP category exists, thereby preventing the positive rule from
Rule: NotPersonReverse
Priority: 20
// we don't want to match ''Jones, I''
{Token.category == NNP}
{Token.string == ","}
{Token.category == PRP}
Rule: PersonReverse
Priority: 5
// we want to match ''Jones, F.W.''
{Token.category == NNP}
{Token.string == ","}
:person -->
- Matching special characters. To specify a single or double quote as a string, precede it with a
backslash, e.g.
will match a double quote. For other special characters, such as "$", enclose it in double quotes, e.g.{Token.category == "PRP\$"}
- Referring to previous annotations. An annotation generated in one phase can be referred to in a later phase, in exactly the same way as any other kind of annotation (by specifying the name of the annotation within curly braces). The features and values can be referred to or omitted, as with all other annotations. Make sure that if the Input specification is used in the grammar, that the annotation to be referred to is included in the list.
- Using context. Specify left or right context around a pattern by enclosing it in round brackets
outside the round brackets of the pattern. In the example below, the context "in" must
precede the location to be annotated. Only the location will be annotated, but it is
important to remember that context is consumed by the rule, so it cannot be reused in
another rule within the same phase. So, for example, right context cannot be used as left
context for another rule.
// in PARIS
{Token.string == "in"}
{Lookup.majorType == location}
- Debug. Add the following to the options at the top of the grammar.
Options: control = appelt debug = true
- Avoid conflicts. If two possible ways of matching are found for the same text string, a conflict can arise. Normally this is handled by the priority mechanism (test length, rule priority and finally rule precedence). If all these are equal, Jape will simply choose a match at random and fire it. This leads ot non-deterministic behaviour, which should be avoided.
- Using Java code on the RHS. If you want to be flash, you can use any Java code you like on the RHS of the rule. This is useful for feature percolation (see below), for deleting previous annotations, measuring length of strings, and performing alternative operations depending on particular features of the annotation. See 7.7 for more details.
- Feature percolation. To copy features from previous annotations, where the value of the feature is unknown, some simple Java code can be used. See Section 7.7 for a more detailed explanation of this.
- Adding a feature to the document. Instead of adding a feature to an annotation, a
feature can be added to the document as a whole. For example, the following
code on the RHS would add the feature "texttype" with value "sport" to the
doc.getFeatures().put("texttype", ''sport'');
- Overlapping annotations. Once JAPE has matched something, that part of the input is
"consumed" and it moves on to the next position. This means that it does not recognise
overlapping annotations in patterns, e.g. where matching overlapping lookups from the
gazetteer. For example, for a string "hALCAM" with the lookups "hAL", "ALCAM" and
"CAM", only the first lookup "hAL" will be recognised by the grammar rule that matches
lookups. After the grammar has matched "hAL" it will continue with "CAM" hence skipping
"ALCAM" completely.
The trick to handle this kind of situations is to delete the used up lookups and run again the same grammar over the same input. You may need to repeat this several times until you've used up all your lookups. The number of repetitions required needs to be determined experimentally.
7.6 Ontology aware grammar transduction [#]
GATE supports two different methods for ontology aware grammar transduction. Firstly it is possible to use the ontology feature both in grammars and annotations, while using the default transducer. Secondly it is possible to use an ontology aware transducer by passing an ontology language resource to one of the subsumes methods in SimpleFeatureMapImpl. This second strategy does not check for ontology features, which will make the writing of grammars easier, as there is no need to specify ontology when writing them. More information about the ontology-aware transducer can be found in Section 10.6.
7.7 Using Java code in JAPE rules [#]
The RHS of a JAPE rule can consist of any Java code. This is useful for removing temporary annotations and for percolating and manipulating features from previous annotations. In the example below
The first rule below shows a rule which matches a first person name, e.g. "Fred", and adds a gender feature depending on the value of the minorType from the gazetteer list in which the name was found. We first get the bindings associated with the person label (i.e. the Lookup annotation). We then create a new annotation called "personAnn" which contains this annotation, and create a new FeatureMap to enable us to add features. Then we get the minorType features (and its value) from the personAnn annotation (in this case, the feature will be "gender" and the value will be "male"), and add this value to a new feature called "gender". We create another feature "rule" with value "FirstName". Finally, we add all the features to a new annotation "FirstPerson" which attaches to the same nodes as the original "person" binding.
Note that inputAS and outputAS represent the input and output annotation set. Normally, these would be the same (by default when using ANNIE, these will be the "Default" annotation set). Since the user is at liberty to change the input and output annotation sets in the paramters of the JAPE transducer at runtime, it cannot be guaranteed that the input and output annotation sets will be the same, and therefore we must specify the annotation set we are referring to.
Rule: FirstName
{Lookup.majorType == person_first}
gate.AnnotationSet person = (gate.AnnotationSet)bindings.get("person");
gate.Annotation personAnn = (gate.Annotation)person.iterator().next();
gate.FeatureMap features = Factory.newFeatureMap();
features.put("gender", personAnn.getFeatures().get("minorType"));
features.put("rule", "FirstName");
outputAS.add(person.firstNode(), person.lastNode(), "FirstPerson",
The second rule (contained in a subsequent grammar phase) makes use of annotations produced by the first rule described above. Instead of percolating the minorType from the annotation produced by the gazetteer lookup, this time it percolates the feature from the annotation produced by the previous grammar rule. So here it gets the "gender" feature value from the "FirstPerson" annotation, and adds it to a new feature (again called "gender" for convenience), which is added to the new annotation (in outputAS) "TempPerson". At the end of this rule, the existing input annotations (from inputAS) are removed because they are no longer needed. Note that in the previous rule, the existing annotations were not removed, because it is possible they might be needed later on in another grammar phase.
Rule: GazPersonFirst
gate.AnnotationSet person = (gate.AnnotationSet)bindings.get("person");
gate.Annotation personAnn = (gate.Annotation)person.iterator().next();
gate.FeatureMap features = Factory.newFeatureMap();
features.put("gender", personAnn.getFeatures().get("gender"));
features.put("rule", "GazPersonFirst");
outputAS.add(person.firstNode(), person.lastNode(), "TempPerson",
7.7.1 Adding a feature to the document
The following example code shows how to add the feature "genre" with value "email" to the document, using JAVA code on the RHS of a rule:
Rule: Email
Priority: 150
doc.getFeatures().put("genre", "email");
7.7.2 Using named blocks [#]
For the common case where a Java block refers just to the annotations from a single left-hand-side binding, JAPE provides a shorthand notation:
Rule: RemoveDoneFlag
{Instance.flag == "done"}
Annotation theInstance = (Annotation)instAnnots.iterator().next();
This rule is equivalent to the following:
Rule: RemoveDoneFlag
{Instance.flag == "done"}
AnnotationSet instAnnots = (AnnotationSet)bindings.get("inst");
if(instAnnots != null && instAnnots.size() != 0) {
Annotation theInstance = (Annotation)instAnnots.iterator().next();
A label :<label> on a Java block creates a local variable <label>Annots within the Java block which is the AnnotationSet bound to the <label> label. Also, the Java code in the block is only executed if there is at least one annotation bound to the label, so you do not need to check this condition in your own code. Of course, if you need more flexibility, e.g. to perform some action in the case where the label is not bound, you will need to use an unlabelled block and perform the bindings.get() yourself.
7.7.3 Java RHS overview [#]
When a JAPE grammar is parsed, a Jape parser creates action classes for all Java RHSs in the grammar. (one action class per RHS) RHS Java code will be embedded as a body of the method doIt and will work in context of this method. When a particular rule is fired, the method doIt will be executed.
Method doIt is specified by the interface gate.jape.RhsAction. Each action class implements this interface and is generated with the following template:
import java.io.*;
import java.util.*;
import gate.*;
import gate.jape.*;
import gate.creole.ontology.Ontology;
import gate.annotation.*;
import gate.util.*;
class <AutogeneratedActionClassName>
implements java.io.Serializable, RhsAction {
public void doIt(Document doc,
java.util.Map bindings,
AnnotationSet annotations,
AnnotationSet inputAS,
AnnotationSet outputAS,
Ontology ontology) {
// your RHS Java code will be embedded here
Method doIt has the following parameters that can be used in RHS Java code:
- Document doc - a document that is currently processed
- java.util.Map bindings - a map of binding variables where a key is a (String) name of binding variable and value is (AnnotationSet) set of annotations corresponding to this binding variable
- AnnotationSet annotations - Do not use this (it's a synonym for outputAS that is still used in some grammars but is now deprecated).
- AnnotationSet inputAS - input annotations
- AnnotationSet outputAS - output annotations
- Ontology ontology - a GATE's transducer ontology
In your Java RHS you can use short names for all Java classes that are imported by the action class (plus Java classes from the packages that are imported by default according to JVM specification: java.lang.*, java.math.*). But you need to use fully qualified Java class names for all other classes. For example:
// VALID line examples
AnnotationSet as = ...
InputStream is = ...
java.util.logging.Logger myLogger =
java.sql.Statement stmt = ...
// INVALID line examples
Logger myLogger = Logger.getLogger("JapePhaseLogger");
Statement stmt = ...
7.8 Optimising for speed [#]
The way in which grammars are designed can have a huge impact on the processing speed. Some simple tricks to keep the processing as fast as possible are:
- avoid the use of the * and + operators. Replace them with ? where possible. For example,
instead of
use({Token})? ({Token})? ({Token})?
if you can predict that you won't need to recognise a string of Tokens longer than 3.
- avoid specifying unnecessary elements such as SpaceTokens where you can. To do this, use the Input specification at the beginning of the grammar to stipulate the annotations that need to be considered. If no Input specification is used, all annotations will be considered (so, for example, you cannot match two tokens separated by a space unless you specify the SpaceToken in the pattern). If, however, you specify Tokens but not SpaceTokens in the Input, SpaceTokens do not have to be mentioned in the pattern to be recognised. If, for example, there is only one rule in a phase that requires SpaceTokens to be specified, it may be judicious to move that rule to a separate phase where the SpaceToken can be specified as Input.
- avoid the shorthand syntax for copying feature values (newFeat = :bind.Type.oldFeat), particularly if you need to copy multiple features from the left to the right hand side of your rule.
7.9 Serializing JAPE Transducer [#]
JAPE grammars are written as files with the extension ".jape", which are parsed and compiled at run-time to execute them over the GATE document(s). Serialization of the JAPE Transducer adds the capability to serialize such grammar files and use them later to bootstrap new JAPE transducers, where they do not need the original JAPE grammar file. This allows people to distribute the serialized version of their grammars without disclosing the actual contents of their jape files. This is implemented as part of the JAPE Transducer PR. The following sections describe how to serialize and deserialize them.
7.9.1 How to serialize?
Once an instance of a JAPE transducer is created, the option to serialize it appears in the option menu of that instance. The option menu can be activated by right clicking on the respective PR. Having done so, it asks for the file name where the serialized version of the respective JAPE grammar is stored.
7.9.2 How to use the serialized grammar file?
The JAPE Transducer now also has an init-time parameter binaryGrammarURL, which appears as an optional parameter to the grammarURL. The User can use this parameter (i.e. binaryGrammarURL) to specify the serialized grammar file.
7.10 The JAPE Debugger [#]
The Jape debugger helps to find errors in Jape programs enabling the user to see in detail how a Jape rule works when applied to a particular range of text. It was written by Ontos, who also provided the original version of this documentation. The debugger allows the user to select a particular part of the text, and then look at the detailed history of processing. This will enable them to see which rules were matched and which were not, and also why particular rules were or were not matched. It is also possible to set breakpoints for particular rules, enabling the user to see how the rule was matched, and what annotations were created.
The Jape debugger could be useful in situations where the old simple DEBUG OUTPUT method does not help. For example when:
- A Rule LHS has not been matched.
- Text did not match the expected template of a rule.
- The rule was overridden by another conflicting rule.
- Annotations are created, but it is not possible to tell which rule created them.
7.10.1 Debugger GUI
The layout of the JAPE-debugger user interface is shown in Figure 7.1.
The debugger's main frame consists of the following primary components:
- Resources tree (appears in the left side of the main frame and contains all the resources available within the current GATE session).
- Debugging panel (located at the center of the main frame and contains three tabs providing all necessary debugging information).
- Document panel (provides you with the document on which you are currently debugging).
7.10.2 Using the Debugger
In most situations you will use the debugger in trace mode using the following steps:
- initialize JAPE-debugger from the GATE menu (Tools / JAPE Debugger);
- run a GATE serial controller (This can be done either from GATE or from the debugger. Note: for performance reasons, the debugger doesnt gather matching information when its not running, so run GATE serial controller after you open the debugger window);
- select the part of the text that is interesting for debugging purposes, and press the button at the left of the text to update the view of the debugger.
After these steps the following information becomes available. In the Resources tree some of the rules become highlighted in different colors:
- Green means that the rule has matched successfully.
- Yellow means that it matched, but was overridden by another rule.
- Red means that the rule tried to match, but failed.
Trace history is the main debugging tab in Debugging panel. It contains the source of the JAPE rule currently selected, and the selected text in the document panel. All the inputs are shown, and matched inputs are highlighted in green. Annotations, which made the rule fail, are highlighted in red. If a rule tried to match more than one time on the selected text interval, buttons on the top of the panel (Previous and Next) become enabled, and allow one to observe all the matching attempts of the rule. Clicking on any of the inputs shows an annotation window, and the tool tip of the matched words gives the template in the rule.
Step by Step Example
To give an idea of how to use debugger for fixing bugs, lets consider the following example. For instance, there is a rule named PersonFullExt, which should find person names: A. B. Dick, J. F. Kennedy and so on, and create an annotation Person. To test the rule, we run GATE on a text fragment containing the following words: the J.L. Kellogg Graduate School, so we would expect that the part of the text J. L. Kellogg should get an annotation Person. Unfortunately, we encounter a problem (because only L. Kellogg was matched), so we decide to use the debugger to find the reason for this unexpected behavior. With JAPE-debugger, it is possible to observe everything needed during for finding and fixing the error.
The appropriate screenshot is shown in Figure 7.2.
As you can see, the rule NotPersonFull matched the text 'the J', so the rule PersonFullExt could start matching only after the pointer has moved to the token '.'. Without the debugger, it wouldn't be so easy to find the reason for this error, because the rule NotPersonFull doesn't create any annotations.
An additional feature of the debugger is the availability of debugging with breakpoints (Jape Rule Tab). After setting a breakpoint on a given rule (in our case it is the rule named TheOrgXBase), the GATE transducer will be interrupted at the breakpoint, and in the document panel the text that is currently matched by the rule (it is highlighted in cyan) will be displayed. In the tab, a special table representation of the rule (with what it matches on the left side), and the history of annotations created by this rule, will be displayed, as in Figure 7.3.
7.10.3 Known Bugs
1. Debugger doesn't see processing resource reinitialization. A possible workaround is to close and open the resource again.
7.11 Notes for Montreal Transducer users [#]
In June 2008, the standard JAPE transducer implementation gained a number of features inspired by Luc Plamondon's "Montreal Transducer", which has been available as a GATE plugin for several years. If you have existing Montreal Transducer grammars and want to update them to work with the standard JAPE implementation you should be aware of the following differences in behaviour:
- Quantifiers (*, + and ?) in the Montreal transducer are always greedy, but this is not necessarily the case in standard JAPE.
- The Montreal Transducer defines {Type.feature != value} to be the same as {!Type.feature == value} (and likewise the !~ operator in terms of =~). In standard JAPE these constructs have different semantics. {Type.feature != value} will only match if there is a Type annotation whose feature feature does not have the given value, and if it matches it will bind the single Type annotation. {!Type.feature == value} will match if there is no Type annotation at a given place with this feature (including when there is no Type annotation at all), and if it matches it will bind every other annotation that starts at that location. If you have used != in your Montreal grammars and want them to continue to behave the same way you must change them to use the prefix-! form instead (see section 7.4).
- The =~ operator in standard JAPE looks for regular expression matches anywhere within a feature value, whereas in the Montreal transducer it requires the whole string to match. To obtain the whole-string matching behaviour in standard JAPE, use the ==~ operator instead (see section 7.1.3).
1A good description of the original version of this language is in Doug Appelt's TextPro manual. Doug was a great help to us in implementing JAPE. Thanks Doug!
2We might be more specific and state the possible lengths of the number, but within the confines of this project we currently have no need to, because there is no ambiguity with anything else
3This syntax will be familiar to Groovy users.
4However this does mean that it is not possible to include an n, r or t character after a backslash in a JAPE quoted string, or to have a backslash as the last character of your regular expression. Workarounds include placing the backslash in a character class ([\\]—) or enabling the (?x) flag, which allows you to put whitespace between the backslash and the offending character without changing the meaning of the pattern.
5In the Montreal transducer, the two forms were equivalent


text:
Thursday Seminar: Genome dynamics and the evolution of germline/soma distinctions across the (eukaryotic) tree of life
In contrast to the typified view of genomes as fixed within species, we find considerable evidence for genome dynamics (e.g. cyclical polyploidization, chromosomal rearrangements) across the eukaryotic tree of life. Based on these data, we hypothesized that LECA, the last eukaryotic common ancestor, had a dynamic genome that used epigenetic mechanisms to distinguish germline (i.e. to be inherited) from somatic genome material. Though fewer data exist for bacteria and archaea, there is also evidence of genome dynamics among these lineages suggesting either multiple or very ancient origins of the dynamic processes. Together, these data challenge ideas on the nature of genomes across the tree of life.
Host: Professor Tim James
Coffee and cookies will be served at 4 p.m.

subset: commoncrawl


text:
This Post is part of the "FREE Wholesale Training Course". You can view the entire course listing and introduction to the course here.
You are here:
Module 3: Value Propositions
- Introduction to value propositions
- Defining value propositions
- Building a company website
- Building social media accounts
- Other Marketplaces / International
- Bundling products on Amazon
- Creating New Listings and Listing Optimization
- Paid advertising (PPC)
- Other value proposition ideas
You can click on each of the links above to go directly to the area of the module the best interests you. That being said, lets get right into the content!
Want to skip reading the massive wall of text? After the entire course is released, I will make videos for each of the sections for easier consumption. Make sure you are on our mailing list to be notified when it's released!
Disclosure: Some of the links on this page are affiliate links. If you choose to purchase items after clicking on the links, I will receive a small commission for the referral. Keep in mind, there is no additional cost to you for using those links. By clicking on the links, it helps support me and the site, and allows me to keep pumping out awesome content! If you have any questions about any of the companies / services / items I've linked to, feel free to contact me and I'll help!
Bundling Products on Amazon
You've been doing research on a lot of products, and you realize there just isn't margin in anything you look at. It's frustrating you to no end, because you've been able to land wholesale accounts – just none of them are any good. You can't make any money! What should you do?
Create Bundles!
Bundling is a strategy you can use to create a new listing on Amazon, which reduces buy box competition and increases margins. The basic definition of product bundling is when you offer multiple products together in one listing for a customer. Let's take a look at one way a seller is using a bundle to their advantage:
This seller must have noticed that Amazon is selling on this listing. They knew it was unlikely they would be able to sell this item, because Amazon controls the buy box. What did they do? They realized the USB cord and ac adapter comes with the items, but weren't included in the original image on the Amazon listing. If you look at the image below at #1, you can see where they added that USB cord and ac adapter. This is more of a "listing optimization" technique than a bundling technique, because they are showing greater value in the image, which should improve conversions.
Next, if you look at #2 in the image, you can see they added a gift box to the listing. In a traditional sense, just adding a gift box isn't exactly within Amazon's bundling guidelines. However, in this example, this seller is sitting in a gray area because the listing is bundling the watch and the activity band, which are items that are sold separately. Amazon themselves just happens to have a bundle of these two items together. Overall, even though this sits in a gray area, it likely satisfies most Amazon guidelines for a bundle.
There are a few reviews on that new bundle listing which tells you people are buying it. In this case, most sellers would just skip this product because Amazon is selling this item. This seller got creative, and they are now making money on an otherwise "dead" item.
Now that we've seen one example of a bundle, let's go over guidelines for a bundle. It's always smart to go directly to the source for polices regarding things like this, so let's see what Amazon says about bundling:
Those seem pretty simple right? Well, they had to clarify some things as Amazon sellers took advantage of loopholes:
If you remember the bundle in the example, it's borderline breaking the "Bundles consist of multiple single items that can each be identified by a unique ASIN/UPC and are sold together as a single offering. A pre-packaged kit or pack with multiple items that is identified by a single ASIN/UPC is not considered a bundle." policy. Garmin does sell the item as a pre-packaged kit, but also separately. If the seller is bundling the separate items together and not using the pre-packaged kit, they are in line with this policy. If they are using the pre-packaged kit, they are not in line with the policy. See why I called it a gray area? There's no way to know without ordering the product.
There's a few other notes from the detailed policy I would like to address:
You need to have your own UPC code to create bundles. Most sellers typically purchase UPC codes from UPC code resellers such as Speedy Barcodes. There is a bit of an issue with doing so. Recently, Amazon started matching UPC codes to the GS1 database. (GS1 is who issues UPC codes, and they keep a database of all the codes they issue). When you buy from a company like Speedy Barcodes, you are purchasing UPC codes that are tied that that company. If you attempt to use one of those paid UPC codes to create a bundle and it doesn't match what Amazon is expecting for a specific brand, Amazon may not allow you to create the listing. The way some sellers are getting around this is by changing the Brand on the listing to something else. For example, the listing above has a brand name "Garmin", because all the items in the bundle are Garmin items. The seller possibly could have used "Fitness Gift Packs" as the brand name. Keep in mind, this would potentially be mis-representing the item, because "Fitness Gift Packs" isn't the actual manufacturer. One way around this would be to find a non-Garmin item to bundle with, which gives you two manufacturers / brands for the bundle. There's no specific guideline that says which manufacturer / brand you are required to use for a bundle with multiple manufacturers / brands. Assuming you have a DBA of your company as "Fitness Gift Packs", it wouldn't be a stretch to be able to use that name as the manufacturer / brand for that listing. This is a very gray area, and is something that Amazon could change a policy on, or clamp down on in the future. When sellers use gray areas, Amazon tends to change policies to eliminate those gray areas. Just keep this in mind, and determine if it's worth the risk for your business.
- You need to have branded products, and can't use generic products as part of a bundle. But, you can somewhat use this to your advantage. Let's say you find a company that sells a lot of generic items. It's possible you could contact the manufacturer and ask if you can private label / white label their already made generic items. If they are willing to do so, you can design some new packaging, and use a brand name of your own for that product. Now, you have a branded product that can be used with a larger brand name product. Sticking with the Garmin example above, if you found a generic activity band, you could brand the activity band with your name, and sell it with the Garmin product.
- Bundles should have products that compliment each other. This means don't bundle a Monster High doll with a toaster. But do bundle three different Monster High dolls together with a Monster High stationary set, a Monster High sticker set, and a gift box. We'll go into more detail below on how to find appropriate bundle ideas.
Ok, great. Any more things I should know about bundles?
Yep. There's also policies for titles, product details, and images:
Of all the bundle guidelines that aren't followed by sellers, the title guideline is the one that seems to be skipped the most. A lot of sellers don't use the word "bundle" in the title, even though they are required to. Just keep this in mind while researching bundles yourself, and when creating your own listings.
Now that's we've seen one example, and know Amazon's policies, lets look at a few other examples. Since every bundle is supposed to have the word "bundle" in it, I'm going to do a search on Amazon for the word "bundle" to find some bundles for examples. Then, I'm going to choose a sub-category to find them. In this example, I'm going to use Health, Household & Baby Care from the search drop down box.
After doing that search, I found quite a few different bundles to use as an example. Here's one that caught my eye:
This a bundle of multiple health and beauty products from the same brand owner. If you search for each of the parts individually, there are listings for each of them. Some of them have decent BSR's, and some do not. This is a perfect example of taking a good selling product, and bundling it with products that don't sell as well. When searching through lists of UPC codes from a brand owner, you might see a few good selling items that have no margin, and a bunch of poor selling items that have a lot of margin. Is there a way to combine some of those products into a bundle?
Let's break down some relevant parts of this bundle in the image above:
- The image is showing all of the relevant parts of this bundle.
- First bullet point of the product shows specifically what's part of the bundle.
- This one is kind of slick. They have created this bundle as a variation of a product. This allows all of the other products to get additional exposure. Or, it's possible one of the other variations was selling well, so they added this bundle to capitalize on the traffic.
Let's move on to a grocery department example.
This bundle is a little different, as it has quite a few different kinds of snacks from all different brand owners. You can find these other items on Amazon in many different listings, but in a lot of cases they are multipacks. What makes this a little unique is they are targeting people looking for a "care package", which is in the title.
Let's break down some relevant parts of this bundle in the image above:
- This brand name is different than we saw in the other two. Mainly because it has items from multiple brands, so they couldn't use one specific brand for the listing. They had to "make one up". In theory, they should have the name "Hangry Kit" as a DBA if they are the "manufacturer" of this product. It's unlikely they do, but technically that should be the case.
- Multiple images showing they are using custom packaging for this bundle. This makes it much harder for "hijackers" to hop on the listing.
- They put everything into a branded box. This is extremely smart, as it makes it nearly impossible for anyone else to sell this item. If this company hasn't trademarked the term "Hangry Kit", someone could make this exact same bundle if they get boxes made that exactly match the bundle. If I were this seller, I would make sure I trademarked that term, and had a DBA for that name. If they did that, the company could file for brand registry and likely lock out other sellers.
There are a few things they are doing against Amazon guidelines that I would like to point out. They do not use the word "bundle" in the title. In addition, they don't list the contents of the bundle in the first bullet point. Finally, they also are saying this in the product description:
They are saying they may substitute items if they run out of stock – which is directly against bundling policy.
Otherwise, I think they actually did a really good job on that specific listing. I point these things out so you can see exactly what looks good, and how other sellers are skirting policies. Just because this seller is doing it, doesn't mean you should too.
Now that you know what a bundle looks like, you may be asking..
How Do I Find A Good Bundle?
If you are totally stumped on how to find good bundles, look at existing bundles on Amazon for ideas. Don't copy exactly what others are doing – just think of different ideas. Just from the examples above, here's some ideas you may be able to think of:
- Are there products with my existing suppliers that would work well together as a gift bundle?
- Do I have a supplier that carries a nice line of complementary products, where a few sell well, but some don't?
- Do I have products that people would want in a care package?
- Is there a twist on these ideas I could use for bundles?
Another good way to find bundles is to use Amazon's "Frequently Bought Together" and "Customers Who Bought This Item Also Bought" areas. When researching products your supplier has, scroll down and look to see what other items customers have bought with it. Let's look at an example..
One of your suppliers carries DYMO printers. Amazon sells all of them. There's no way to compete, right?
Well, let's scroll down the page a little bit, and look at the "Frequently Bought Together" section:
It looks like people usually buy extra labels with their label printer. The two mentioned in this area are DYMO branded labels. You could create a bundle with DYMO labels, or you could find a supplier that sells other labels under a different brand. That would be a great bundle! Complementary, and supports the main product – the printer.
Scrolling down to the "Customers Who Bought This Item Also Bought" area:
This validates that people also buy labels when they buy the printer.
Here's a few other ways to get the ideas flowing:
- Walk into a store, and see how things are positioned together in a specific store. A lot of times similar items are grouped together.
- Are there accessories for the main item you are selling? You could bundle the accessories with the actual main item, or sell multiple accessories as an "accessory package"
- Is there a task or problem the main item solves? Bundle multiple items together to ensure it is the "complete solution" for the problem.
- Go to other .com websites for your main product and see what they are suggesting to be purchased with your main product.
- Think of any other ways you can provide value to items. Is there an information pamphlet you could enclose inside the bundle packaging? Ebooks are a no-no, but physical ones are good.
- If you were going to buy a gift for someone, and wanted to buy them multiple items around the same theme, what would you buy?
- Do your items work well for Holidays? Could they be marketed as a specific Holiday package?
How To Make Your Bundles Unique
You've created this awesome bundle. It starts selling extremely well. All of a sudden three other sellers hop onto the listing, selling the same thing you are. Wow, what to do now? It's already too late! When you create your bundles, you want to try and make them as unique as possible, which makes it difficult for other sellers to replicate.
Here's some ideas to make your bundles unique:
- Create your own packaging with a logo / tag line, and make sure it is included in the images. This is the same thing the Hangry Kit listing did.
- Create listings with items that have to be sourced from multiple brand owners / manufacturers. By doing so, a seller would need accounts with multiple suppliers to be able to duplicate the bundle.
- Don't copy other people's bundles. If you are going to make something similar, make it better!
- Create instructional materials included inside the packaging that was written by you.
Now that you know how to create great ideas for bundles, it's time to create and optimize the listings!


text:
Lip Gloss - Blackberry Mousse
Sold out.
Type: Unknown Type
Vendor: Bath Body & Home
Lip Gloss - Blackberry Mousse
Buy direct from Australia's Leading exclusive importer of Bath and Body Works products
Be dazzled! Light reflecting iridescent sparkle gloss illuminates lips. Wand applicator delivers dabs of high shine in our exclusive marbelised formula for a perfect pucker everytime you apply!
- · Sweet and Creamy with a hint of Blackberry
- · A delightful blend of natural ingredients come together to produce this amazing fragrance. Perfect for use day or night.
- · Not tested on animals


text:
During a now famous exchange with Senator John McCain in the first Presidential debate – Obama falsely claimed that Henry Kissinger, the former Secretary of State, Nobel Peace Prize laureate and renown Foreign Policy expert, would support Obama's stated intent of meeting, personally and without pre-condition, with the Iranian President Mahmoud Ahmadinejad. Obama has repeatedly stated, that during the first year of his administration, that he, Obama, would meet with some of the worlds worse tyrants. http://time-blog.com/real_clear_politics/2008/05/obamas_moment_1.html
Originally Obama made the pledge during campaign speeches. Subsequently, in a CNN presidential candidates debate in July 2007, Obama was asked to confirm that he would be willing "without precondition" to meet with the leaders of Iran, Syria, Venezuela, Cuba and North Korea during the first year of his administration. Obama's response, "I would and the reason is this, that the notion that somehow not talking to countries is punishment to them — which has been the guiding diplomatic principle of this administration — is ridiculous." http://www.reuters.com/article/vcCandidateFeed2/idUSN2635405920080527
You might think that Barack's first statement was quite enough, however, Barack went on to add that it was "a disgrace that we have not spoken to them." Obama, apparently, doesn't grasp the concept that you can communicate with a foreign country without the top leaders of the countries meeting face to face. http://copiousdissent.blogspot.com/2007/07/obama-promises-to-meet-with-dictators.html
The only thing that could be more outrageous than Obama's statement that Doctor Kissinger would support his foolish position, is the thought process that allowed Barack to believe his comment would go unchallenged. Really, what was he thinking?
Senator McCain immediately begged to differ, saying that Kissinger, his friend of 35 years, believes quite the opposite — as would any foreign policy realist who was not entirely clueless of how the real world works.
Barack then attempted to back-pedal out of this mess of his own making, but he stumbled and then fell on his face. Again, Barack invoked Henry Kissinger, insisting that the Doctor was a supporter of his illogical position.
Stephen Hayes of the Weekly Standard contacted Kissinger shortly after the exchange to find out who was right.
Hayes reports that "Henry Kissinger believes Barack Obama misstated his views on diplomacy with US adversaries and is not happy about being mischaracterized," and quotes Dr Kissinger as saying: "Senator McCain is right. I would not recommend the next President of the United States engage in talks with Iran at the Presidential level. My views on this issue are entirely compatible with the views of my friend Senator John McCain. We do not agree on everything, but we do agree that any negotiations with Iran must be geared to reality." http://www.weeklystandard.com/weblogs/TWSFP/2008/09/tws_exclusive_kissinger_unhapp.asp
Filed under: Barack Obama, Debate, Henry Kissinger, John McCain | Tagged: Barack Obama, Debate, Henry Kissinger, John McCain | Leave a comment »


text:
Upon receipt of your application packet, you will receive an email confirming receipt of your adoption grant application packet. If any information is missing you will be notified of that as well.
Adoption assistance grant applications are reviewed monthly.
Adoption Grant Selection Committee
All applications will be reviewed by the Grant Selection Committee. Every effort will be made to present your application to the committee at the time most favorable for your particular situation.
You will be notified via email when your application will be presented to the committee, you will be given the opportunity to update your application prior to review.
Adoption Grant Decision Process
The Grant Selection Committee, made up of one elected representative from each regional chapter, will review your application and either: approve it for a grant, decline to award a grant, or recommend a local Gift of Adoption Chapter approve your application for a grant.
You will be notified of the decision via email within 48 hours of the Grant Selection Committee meeting.
If You are Approved for an Adoption Assistance Grant
If your application is approved by the Grant Selection Committee it is possible it may be advanced to the regional chapter for a final funding decision. If this is the case, you will receive an email alerting you of this decision within 48 hours of the National Grant Selection Committee meeting.
At this time, you will also be invited to provide any additional information you would like the local chapter board to consider in making their decision.
You will receive notification via email of the regional chapter's decision within two weeks of the Grant Selection Committee meeting.
You will receive an email from the Director of Grants providing information on what you will need to do to get your adoption assistance grant award disbursed.
If Your Adoption Grant Application is Declined
If your application is declined, you will be provided an email that will detail the reason(s) why.
We receive many more applications each month than we have funding to support. It is not uncommon for a denial reason to be, quite simply, we do not have enough funds to award every grant that meets our funding criteria.
Please do not lose heart, your application fee entitles you to have your case presented to the committee up to three times, as long as the adoption is not yet finalized and there remains an outstanding balance related to your adoption expenses.
If your situation changes materially after receiving notification that your application was declined, we encourage you to notify us so that we can present it to the Grant Selection Committee again at a future date.
Questions About the Review Process
If you have any questions concerning Gift of Adoption or the application and review process, please visit our FAQs.
If you do not find the answer to your question there, please email us at: email@example.com
Privacy Rights
Information provided in your application is held confidential. Gift of Adoption respects your privacy. The information you provide is used for no other purpose than the consideration of your adoption assistance grant application.


text:
(Reuters) - A Wall Street rally collapsed and stocks turned negative shortly before the market close on Wednesday after investors reassessed the Federal Reserve's policy statement and reduced their risk as they weighed how long the U.S. central bank would continue to raise interest rates.
U.S. stocks initially extended gains after the Fed, as expected, raised interest rates and left its monetary policy outlook for the coming years largely unchanged amid steady economic growth and a strong job market.
But the market reversed course as investors weighed to what degree the elimination of the word "accommodative" from the Fed's policy statement suggested that the end of a cycle of interest-rate hikes might be in sight.
The Fed lifted its benchmark overnight lending rate by a quarter of a percentage point to a range of 2.00 percent to 2.25 percent.
"People misinterpreted the removal of 'accommodative' in the statement," said Mike O'Rourke, chief market strategist at JonesTrading. "People realized that monetary policy remains on course and there are expectations of another rate hike this year, and they unwound purchases they made on the release of the statement, and also additional de-risking going into the close."
The S&P 500 financial index .SPSY fell 1.27 percent, leading declines.
The S&P 500 utilities index .SPLRCU and real estate index .SPLRCR, which are sensitive to interest rates because their components are often favored for their dividend yields, each fell over 1 percent.
The Fed still foresees another rate hike in December, three more next year, and one increase in 2020.
Fed Chairman Jerome Powell said after the policy meeting that the U.S. central bank is closely monitoring inflation, underscoring concerns the U.S. economy's rapid growth could lead to overheating and force the Fed to raise rates further.
Referring to the removal of the word "accommodative," Powell said, "This change does not signal any change in the likely path of policy. Instead, it is a sign that policy is proceeding in line with our expectations."
The stock market has enjoyed a boom period and is at record levels. But as rates rise, equities face rising competition for investors' funds not only from bonds, but also from cash, which is now the most attractive it has been in about a decade.
The Dow Jones Industrial Average .DJI ended down 0.4 percent at 26,385.28 points, while the S&P 500 .SPX lost 0.33 percent to 2,905.97. During the session, the S&P 500 traded up as much as 0.53 percent.
The Nasdaq Composite .IXIC dropped 0.21 percent to 7,990.37.
The S&P 500 health index .SPXHC rose 0.20 percent, led by biotechs, while the newly formed communication services index .SPLRCL rose 0.35 percent, boosted by Facebook (FB.O), which gained 1.24 percent.
Twenty-First Century Fox (FOXA.O) rose 1.02 percent after agreeing to sell its stake in Sky SKYB.L to Comcast (CMCSA.O), which dipped 0.08 percent. Walt Disney Co (DIS.N), which is buying Fox, jumped 1.39 percent.
Nike (NKE.N) fell 1.3 percent as the sportswear maker stuck to its full-year forecast even after sales got a boost from a controversial ad campaign featuring former NFL player Colin Kaepernick.
Declining issues outnumbered advancing ones on the NYSE by a 1.60-to-1 ratio; on Nasdaq, a 1.70-to-1 ratio favored decliners.
The S&P 500 posted 31 new 52-week highs and 12 new lows; the Nasdaq Composite recorded 66 new highs and 73 new lows.
Volume on U.S. exchanges was 7.0 billion shares, compared to a 6.7 billion average over the last 20 trading days.
Reporting by Noel Randewitch; Additional reporting by Amy Caren Daniel in Bengaluru and Caroline Valetkevitch in New York; Editing by Leslie Adler


text:
Augmented Reality: The Future Is Here
The future is here, and it's augmented reality.
Augmented reality, commonly known as AR, came into the spotlight last year when the popular app game Pokémon Go brought the concept into the hands of many nostalgic 20- to 30-year-olds.
Also last year, another popular app, Snapchat, did the same thing. Snap, Inc. developed a new AR feature within its app that was another way to send your friends funny pictures or videos.
This began a whole new outlook for AR and set a precedent for how tech companies introduce it into their own products. The opportunities in AR and the groundbreaking products it could create for companies and consumers alike became a lot more obvious.
Imagining the Possibility
What exactly is augmented reality? Well, it's a live direct or indirect view of a physical, real-world environment that has its elements "augmented" by computer-generated or extracted real-world sensory input such as sound, video, graphics, haptics, or GPS data. Take a look at the picture below...
This is just one example of augmented reality. I took this picture while using the Snapchat app. This is a picture of my desk, and thanks to the app's AR features, I have the capability of adding a computer-generated element to what would normally be just a boring picture or video of my desk and keyboard.
As you can see, the app added a cartoon cactus bunny jumping out of its flowerpot. Of course, it's hard to fully show you how this cartoon is interacting with its real-life surroundings, but believe me, it is.
What we see as the real world now has the capability of being altered and heightened.
And it's not just a matter of placing an item into what we see as "real." Sure, that looks cool, but how does it really benefit us? We've become such a hands-on and interactive society that we want technology to enhance and help us perform our normal, everyday tasks, and that's exactly what AR aims to do.
At least, that's what some of the biggest tech companies around today hope to do.
When It Comes to AR, Companies Are Jumping In
At the Web Summit technology conference, the vice president of business and operations for virtual reality at Google, Amit Singh, predicted "hundreds of millions" of Android devices will be able to engage in AR uses by the end of 2018.
Singh said:
There will hundreds of millions of phones that will be AR ready. And the current stage is... We are helping developers... build the experiences... So that it becomes a daily habit... and once it does, I suspect the natural evolution of monetization comes through...
Augmented reality [will become] a core feature of most Android over the next few years.
At this year's ShopTalk Europe, an event that organizes the world's most innovative and important events for retail and ecommerce, Greg Jones, director of VR and AR at Google, said, "At some point, we're going to look back and think, how did we not have a digital layer on the physical world."
AR is the obvious next step toward effortlessly intertwining our lives with technology.
Recent insight from Google indicated that 34% of its users said they would use AR while shopping, and 61% said they would prefer to shop at stores that offer AR. Jones added, "AR is set to reconnect physical and digital retail."
AR could be the answer to breathing life back into the retail industry. The retail stores that begin investing in the technology could see the growth they so desperately need.
And Google isn't the only company increasing its traction in the AR realm.
We have you covered! Sign up for Tech Investing Daily's FREE newsletter, Wealth Daily, today and gain first access to actionable stock market commentary, regular IPO updates, and weekly technical analysis. Plus, if you sign up right now, we'll immediately send you our free report: "The Five Most Disruptive Trends In Tech."
A Leak from Apple…
Apple is working on a secret device. Employees from Apple have been working on this secret project for some time now. Jason Stutman, an editor here at Wealth Daily, even wrote about it in a recent article.
But now it's no longer a secret. Last week Bloomberg reported that Apple has been perfecting and developing technology that it will incorporate into an augmented reality headset by 2019, in hopes of having its AR headset in the hands of consumers by 2020.
Apple can't rely on the iPhone to be its only groundbreaking product. It's been 10 years since it shook the market, and it's time for the company to bring something new to the table. What better way to do that than with augmented reality?
Where Is AR Going?
In 2016, the augmented reality market was valued at $2.39 billion, and ReportsnReports is expecting the market to reach $61.39 billion by 2023 — that's a compound annual growth rate (CAGR) growth of 55.1%.
AR is going to be a massive market for tech companies like Google and Apple, but it won't stop there. The medical, e-commerce, and retail markets will reap the rewards from this new technology and its expanding market.
Like I mentioned earlier, Apple, the company that helped make the smartphone ecosystem what it is today, is very interested in augmented reality. Apple's CEO Tim Cook continues to speak out about how he's excited and anticipating augmented reality. During a recent quarterly earnings report, Cook spoke to analysts and said:
[Augmented reality] amplifies human performance instead of isolating humans. It's a help for humanity, not an isolation kind of thing for humanity.
Apple has launched its ARKit development platform, a platform that allows developers to create AR apps that overlay digital content over the real world through the iPhone's camera lens.
My colleague Jason Stutman has been closely following Apple's secret project — so closely that he was able to identify a supplier for Apple's early AR headset prototypes. Check out his exclusive report to find out for yourself.
The opportunity that lies within augmented reality is very real, and you'll regret not becoming part of it when you had the chance.
Until next time,
Monica Savaglia
Wealth Daily
The Best Free Investment You'll Ever Make
We never spam! View our Privacy Policy
After getting your report, you'll begin receiving the Wealth Daily e-Letter, delivered to your inbox daily.


text:
The teachings of Buddha ( meaning 'one who is awake to the reality') have left a profound effect on millions across the world. Even though Buddha's teachings are over thousands of years old they are still pearls of wisdom that have been passed on from one generation to the other. He has inspired people to lead a meaningful life and soothe the aching souls giving them a new direction in life. Buddha's timeless teachings hold true still today especially to everyone going through tough times and those looking to find meaning in life. Buddha's simple sayings have a profound effect on many lives. In Buddha's teachings, people from different cultures and upbringings, age, and nationality have found answers to some of the most fundamental questions about life and relationships. Here are some of his sayings that will help you go to another level.
Buddha says, "Happiness never decreases by being shared." Happiness grows when you share it with people just like sorrows tend to diminish when you share them with the loved ones.
Buddha says, "If you light a lamp for someone else it will also brighten your path." When you help someone you yourself get much more in return. Not only is helpfulness a desirable quality but it also makes you truly a gem of a person.
Buddha says, "Your work is to discover your world and then with all your heart give yourself to it." Everyone comes in this life with a predestined purpose and life plan. You are here on this earth to fulfill a task.
Buddha says, "When the student is ready, the teacher will appear." One must always be ready to learn. You can learn from just about anyone the only thing you need is the will.
Buddha says, "Even death is not to be feared by one who has lived wisely." The life we live is full of various ups and downs, the only way forward is to expect every aspect of it with open arms.
Buddha says, "In the sky, there is no distinction of east and west; people create distinctions out of their own minds and then believe them to be true." Everyone is born equal. Learn to embrace people for who they are , do not judge anyone for their material possessions.
Buddha says, "Better than a thousand hollow words is one word that brings peace." Words have the power to make or break you so the next time you speak, speak wisely.
Buddha says, "Chaos is inherent in all compounded things. Strive on with diligence." Learn to embrace the fact that people will come and go with all the life's complexities and chaos but you must strive with diligence.
Buddha says, "Holding on to anger is like grasping a hot coal with the intent of throwing it at someone else; you are the one who gets burned." When you get angry your emotions get the better of you and logic moves out of the window. So control your anger and use your rationale.
Buddha says, "Your worst enemy cannot harm you as much as your own unguarded thoughts. But once mastered, no one can help you as much." Your mind is your biggest treasure and worst enemy, it's up to you what you want to make of it.
* * *


text:
Kela is responsible for producing and maintaining the Kanta Services.
Kela is committed to protecting the privacy of the users of its web service and its clients.
Kela cannot identify an individual user of the kanta.fi web service on the basis of the data it has gathered as it does not collect the name, contact details or personal identity code of the user of its website. In the Extranet, the user logs in to the service with the Katso ID. The Extranet user log is subject to the privacy policy of Extranet.
The behavioural data collected in the kanta.fi website is not connected to the login data of Kanta Extranet or to the login data of My Kanta Pages or any other data that identifies the individual user and that Kela may process in other contexts.
The My Kanta Pages service gathers data about the number of logins and logouts. The personal identification data of the person logging in to the service is not gathered. Information about the movements or browsing behaviour of the person in My Kanta Pages is not gathered, either.
Kela and its partners use cookies and corresponding technologies (hereinafter cookies in general) in the kanta.fi web service open to everyone. Cookies are used for collecting information about how and when the kanta.fi online service is used. This information helps to improve the availability of the online service.
The user can control the use of cookies with browser settings or by visiting the websites of Kela's partners. The user's options are discussed in further detail in sections 6 and 7 of this privacy policy.
This privacy policy gives answers to the following questions:
- What are Kela's contact details?
- What are cookies and what kind of information do they gather?
- What kind of information does the Kanta Services gather on social media websites?
- For what purpose are cookies and the related information used?
- For how long is the information retained?
- What options do I have with regard to cookies?
- What other kinds of options do the users have?
- Who is the data shared with or where is it transferred to?
- How is the data protected?
- What is the procedure of making changes to the privacy policy?
Contact details
Social Insurance Institution of Finland (Kela)
P.O. Box 450, 00101 Helsinki or Nordenskiöldinkatu 12, 0250 Helsinki
telephone 020 634 11
Contact person:
Pipsa Lotta Marjamäki, Director of Communications, tel. 020 634 1419
What are cookies and what kind of information do they gather?
As is the case with many other web services, the kanta.fi web service uses cookies and other similar technologies. A cookie is a small text file that is stored on the user's device, saving information about the visit to the kanta.fi web service.
If the user continues to browse the kanta.fi web service after being offered information and options with regard the use of the service, the user accepts the installation of cookies. The user's options are discussed in further detail in sections 6 and 7 of this privacy policy.
Logging in to the Extranet in the Kanta Services takes place with the Katso ID. The user data is based on an SAML message, which is as secure as possible from the user's point of view. Identification is based on SSL encryption. The identification service only records the session data, not user data. The behavioural data and cookie data for identification gathered with the cookies of the kanta.fi web service cannot be connected. The application server also collects cookies to enable the user's session functionality. Kela does not utilise or gather this data in other ways.
Cookies are used in the kanta.fi web service for collecting information, for example,
- how many users there are on the website
- which devices are used for accessing the kanta.fi website
- from which web address the users of the online service have entered the website
- which individual pages the users have visited.
Cookies and the servers in the kanta.fi web service automatically save the page requests made by visitors to the website. The information usually contains the network request by the user, the date and time of the request, the IP address of the user's device, and the type and language of the browser.
Due to the principal format of the cookie and log data, it cannot be connected to an individual user without further information. Cookies and server logs are not used for saving, for example, the user's name, email address, telephone number or home address. Kela cannot connect information gathered with cookies to an individual person and is aiming to further improve the anonymity of data. For example, as part of the use of web analytics, numbers are removed from the user's IP address to prevent anyone from identifying the individual user.
What kind of information does the Kanta Services gather on social media websites?
The Kanta Services has a Facebook page for Kanta. With respect to the visitor data of the Facebook site, Facebook and Kela are joint controllers. Further information about the processing of personal data is available in the Facebook privacy notice.
The Kanta Services processes only statistical data regarding the likes and visits to the Facebook site and the visibility of publications, and no individual user can be identified from the data. The Facebook visitor data helps the Kanta Services to understand what kind of contents would be interesting to the public. The statistical data is used for developing the contents to serve the target audience even better.
The kanta.fi web service may also include links to other external websites, and Kela is not responsible for their privacy practices.
For what purpose are cookies and the related information used?
Ensuring technical functioning and data security of the online service
Cookies enable us to ensure that the kanta.fi web service is functioning as it should and that its data security is in order.
Analysis and development of the web service
Web analytics tool Piwik Pro (piwik.pro) use cookies to gather statistical data. Data is gathered in order to analyse visitor numbers, the degree of interest in the contents and the ways of using the service, and to develop the web service.
Further information about the partners of the kanta.fi web service and the purposes of using cookies is presented in the following:
Piwik Pro
- Purpose of using cookies: gathering and analysis of statistical data concerning the web service in order to develop the service.
- Further information about the use of cookies by Piwik Pro (piwik.pro)
For how long is the information retained?
Cookies are valid for the duration of each session until the user closes the browser, or they are so-called persistent cookies that are valid from a few months to a number of years. The user can disable or delete the cookies at any time in the browser settings as described in further detail in section 6.
Data gathered in Google Analytics will not expire automatically. Data accumulated in Piwik Pro is normally retained for 3 years. It is not possible to identify individual users on the basis of the data: for example, in Piwik Pro, every visit is unique, i.e. different visits by the same user cannot be connected to one another.
What options do I have with regard to cookies?
You can prevent and have an impact on the processing of cookies by visiting our partner websites.
Piwik Pro
The user can prevent gathering of data by switching on the Do not track function in the browser settings. See browser-specific instructions: Internet Explorer (microsoft.com), Firefox (mozilla.org) and Google Chrome (google.com).
You can also disable or remove cookies in the web browser settings. Please note that the disabling or removing of cookies may have an impact on the selections you have previously made on the above-mentioned partners' websites, for example, delete cookies installed on the partner website in order to opt out of targeted advertising. Also note that your selections are browser-specific, i.e. you need to make separate selections in each browser you are using.
How to delete cookies in Google Chrome, Internet Explorer and Mozilla Firefox
Google Chrome 66
- Open Google Chrome.
- Click the icon on the upper right-hand corner and select Settings.
- Select Show advanced settings.
- Select the Content settings button under the Privacy heading.
- Under Cookies, uncheck "Allow sites to save and read cookie data (recommended)."
Internet Explorer 11
- Open Internet Explorer.
- Click the Cogwheel icon (Tools) and then select Internet settings.
- Select the Security tab and go to Additional information.
- Check "First party cookies" under option E. Also uncheck "Always allow session cookies".
- Then select OK.
Mozilla Firefox 52
- Open Firefox.
- Click the icon on the upper right-hand corner and select Settings.
- Select Privacy & Security.
- Under History, select the drop-down menu "Firefox will".
- Select "Never remember history" in the drop-down menu.
- Close the Settings page.
Cookies can be enabled again at any time.
Deleting of cookies will not hamper the use of the kanta.fi web service.
However, cookies must be enabled to log in to the Extranet service. The related cookies are necessary in terms of the technical functioning of the service.
What other options do users have?
In addition to having the right to obtain information about the processing of personal data, by virtue of the data protection legislation, users have a right to:
- inspect the personal data recorded of them
- rectify data
- erase data and have the right to be forgotten
- restrict the processing of data
- request the transmission of data from one system to another in the case of automated processing based on consent or contract
- object to processing.
As a rule, in order to implement the above-mentioned rights, Kela needs to be able to identify the individual user. Unless the user provides further information to identify the user and the data related to them, Kela is unable to exercise the above-mentioned rights.
Primarily, the user can have an influence on the processing of data as described above by disabling cookies in the browser settings or by visiting the websites of the partners used. Kela can be contacted by telephone, by submitting a written request to Kela's registry or by visiting a Kela service point in person. The contact details are presented in section 1. The user can also lodge a complaint with the supervisory authority (tietosuoja.fi).
Who is the data shared with or where is it transferred to?
Kela uses reliable partners. The service providers used by Kela (such as media agencies) may have access to the data collected in connection with the use of the web service. The service providers may use this data only for Kela's benefit. In this context, Kela may transfer the personal data processed by it outside the EU or EEA area in compliance with existing legislation.
Kela aims by contract to ensure that the partners and service providers process the data in accordance with the legislation in force at the time.
How is the data protected?
At Kela, data security and the protection of personal data are taken into account methodically in all use and processing of data. The data security and availability of personal data are ensured with appropriate technical and administrative measures. Kela processes all personal data in a secure way and in compliance with the legislation.
All members of Kela's personnel who process personal data are under an obligation of confidentiality. Personal data is only used by persons who need the data in question in their duties in accordance with their access rights.
Data gathered by cookies is also processed by Kela's external partners in accordance with separate agreements. Kela aims to contractually ensure that data security is ensured in the way required by data protection legislation.
Is it possible to make changes to the privacy policy?
From time to time, Kela can make changes to this privacy policy if it is justified, for example, when the purposes of processing change or when changes are made in the recommendations by the authorities or in legislation. Information about the changes will be available in the kanta.fi web service.
The privacy policy of the kanta.fi web service based on the EU General Data Protection Regulation was published on 26 August 2019.


text:
Industrial Cleaning Services - Your business is important to us
M.C.S. is a local company based in Widnes, covering Merseyside, Cheshire and all the North West areas. We have over 30 years experience in the field of Specialised High Pressure Water Jetting and Industrial Cleaning Services. Our services are performed to the highest standard, along with complying with all the necessary Health & Safety requirements. John Farrell the proprietor takes pride that his company is co-operative-flexible-honest.
Our specialist industrial cleaning services and general services include:
- High pressure water jetting
- Contract cleaning & drain maintenance specialists
- High level purified water, pole cleaning system for windows, walls & cladding
- Specialist Clean Room Environment Cleaning Service For Hospitals Laboratories & The Pharmaceutical Industry
- Water Services Sterilisation Chlorination Passivation & Decontamination specialists
- Cleaning and Maintenance Plant Cleaning
- Chemical Cleaning Tank and Boiler Cleaning
- Drain Cleaning and Maintenance
- Carpet and Upholstery Cleaning
- Graffiti Removal & Chewing Gum
- Builders Clean
- General Cleaning - office building and industrial cleaning services
- Stainless Steel Cleaning & Restoration Service


text:
Jul 14, 2016
In this episode we start 155 years in the past, and somehow end up in the future. From the beginning we are reminded of what is really important, and along the way we are introduced to class of person who simply steals their valor. A Richmond rapper has officially arrived, and it isn't just his wit that people are talking about. This summer has had its fair share of snakes, and they have managed to show their faces yet again this week. One of the greatest players of all time (we aren't talking about his baseball career) has finally stopped playing the game, while another game's characters have pulled out of their retirement and stormed back with digital vengeance. Let the augmented reality begin.


text:
Indians' Carlos Carrasco out for season with fractured bone in hand
Indians pitcher Carlos Carrasco has a fractured fifth metacarpal in his right hand and will miss the remainder of the season, manager Terry Francona told reporters.
Carrasco left Saturday's game against the Tigers after being hit in the hand by a line drive.
Carrasco threw just two pitches before Ian Kinsler's line shot struck his throwing hand. The Indians chose to remove him from the game after a brief delay. He was relieved by Jeff Manship.
The Indians lead the Tigers by six games in the AL Central. They are without injured righthander Danny Salazar for the rest of the season, leaving Carrasco and Corey Kluber as Cleveland's two top pitchers. Losing Carrasco would be a major blow to the team's playoff hopes.
Carrasco, 29, is 11–8 with a 3.32 ERA and 1.14 WHIP this season.