Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / docs / usermanual-clusters.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3                "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4   <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
5   <!ENTITY version SYSTEM "version.xml">
6 ]>
7 <chapter id="clusters">
8   <title>Clusters</title>
9   <section id="clusters-and-shaping">
10     <title>Clusters and shaping</title>
11     <para>
12       In text shaping, a <emphasis>cluster</emphasis> is a sequence of
13       characters that needs to be treated as a single, indivisible
14       unit. A single letter or symbol can be a cluster of its
15       own. Other clusters correspond to longer subsequences of the
16       input code points &mdash; such as a ligature or conjunct form
17       &mdash; and require the shaper to ensure that the cluster is not
18       broken during the shaping process.
19     </para>
20     <para>
21       A cluster is distinct from a <emphasis>grapheme</emphasis>,
22       which is the smallest unit of meaning in a writing system or
23       script.
24     </para>
25     <para>
26       The definitions of the two terms are similar. However, clusters
27       are only relevant for script shaping and glyph layout. In
28       contrast, graphemes are a property of the underlying script, and
29       are of interest when client programs implement orthographic 
30       or linguistic functionality.
31     </para>
32     <para>
33       For example, two individual letters are often two separate
34       graphemes. When two letters form a ligature, however, they
35       combine into a single glyph. They are then part of the same
36       cluster and are treated as a unit by the shaping engine &mdash;
37       even though the two original, underlying letters remain separate
38       graphemes.
39     </para>
40     <para>
41       HarfBuzz is concerned with clusters, <emphasis>not</emphasis>
42       with graphemes &mdash; although client programs using HarfBuzz
43       may still care about graphemes for other reasons from time to time.
44     </para>
45     <para>
46       During the shaping process, there are several shaping operations
47       that may merge adjacent characters (for example, when two code
48       points form a ligature or a conjunct form and are replaced by a
49       single glyph) or split one character into several (for example,
50       when decomposing a code point through the
51       <literal>ccmp</literal> feature). Operations like these alter
52       clusters; HarfBuzz tracks the changes to ensure that no clusters
53       get lost or broken during shaping. 
54     </para>
55     <para>
56       HarfBuzz records cluster information independently from how
57       shaping operations affect the individual glyphs returned in an
58       output buffer. Consequently, a client program using HarfBuzz can
59       utilize the cluster information to implement features such as:
60     </para>
61     <itemizedlist>
62       <listitem>
63         <para>
64           Correctly positioning the cursor within a shaped text run,
65           even when characters have formed ligatures, composed or
66           decomposed, reordered, or undergone other shaping operations.
67         </para>
68       </listitem>
69       <listitem>
70         <para>
71           Correctly highlighting a text selection that includes some,
72           but not all, of the characters in a word. 
73         </para>
74       </listitem>
75       <listitem>
76         <para>
77           Applying text attributes (such as color or underlining) to
78           part, but not all, of a word.
79         </para>
80       </listitem>
81       <listitem>
82         <para>
83           Generating output document formats (such as PDF) with
84           embedded text that can be fully extracted.
85         </para>
86       </listitem>
87       <listitem>
88         <para>
89           Determining the mapping between input characters and output
90           glyphs, such as which glyphs are ligatures.
91         </para>
92       </listitem>
93       <listitem>
94         <para>
95           Performing line-breaking, justification, and other
96           line-level or paragraph-level operations that must be done
97           after shaping is complete, but which require examining
98           character-level properties.
99         </para>
100       </listitem>
101     </itemizedlist>
102   </section>
103   <section id="working-with-harfbuzz-clusters">
104     <title>Working with HarfBuzz clusters</title>
105     <para>
106       When you add text to a HarfBuzz buffer, each code point must be
107       assigned a <emphasis>cluster value</emphasis>.
108     </para>
109     <para>
110       This cluster value is an arbitrary number; HarfBuzz uses it only
111       to distinguish between clusters. Many client programs will use
112       the index of each code point in the input text stream as the
113       cluster value. This is for the sake of convenience; the actual
114       value does not matter.
115     </para>
116     <para>
117       Some of the shaping operations performed by HarfBuzz &mdash;
118       such as reordering, composition, decomposition, and substitution
119       &mdash; may alter the cluster values of some characters. The
120       final cluster values in the buffer at the end of the shaping
121       process will indicate to client programs which subsequences of
122       glyphs represent a cluster and, therefore, must not be
123       separated.
124     </para>
125     <para>
126       In addition, client programs can query the final cluster values
127       to discern other potentially important information about the
128       glyphs in the output buffer (such as whether or not a ligature
129       was formed).
130     </para>
131     <para>
132       For example, if the initial sequence of cluster values was:
133     </para>
134     <programlisting>
135       0,1,2,3,4
136     </programlisting>
137     <para>
138       and the final sequence of cluster values is:
139     </para>
140     <programlisting>
141       0,0,3,3
142     </programlisting>
143     <para>
144       then there are two clusters in the output buffer: the first
145       cluster includes the first two glyphs, and the second cluster
146       includes the third and fourth glyphs. It is also evident that a
147       ligature or conjunct has been formed, because there are fewer
148       glyphs in the output buffer (four) than there were code points
149       in the input buffer (five).
150     </para>
151     <para>
152       Although client programs using HarfBuzz are free to assign
153       initial cluster values in any manner they choose to, HarfBuzz
154       does offer some useful guarantees if the cluster values are
155       assigned in a monotonic (either non-decreasing or non-increasing)
156       order.
157     </para>
158     <para>
159       For buffers in the left-to-right (LTR)
160       or top-to-bottom (TTB) text flow direction,
161       HarfBuzz will preserve the monotonic property: client programs
162       are guaranteed that monotonically increasing initial cluster
163       values will be returned as monotonically increasing final
164       cluster values.
165     </para>
166     <para>
167       For buffers in the right-to-left (RTL)
168       or bottom-to-top (BTT) text flow direction,
169       the directionality of the buffer itself is reversed for final
170       output as a matter of design. Therefore, HarfBuzz inverts the
171       monotonic property: client programs are guaranteed that
172       monotonically increasing initial cluster values will be
173       returned as monotonically <emphasis>decreasing</emphasis> final
174       cluster values.
175     </para>
176     <para>
177       Client programs can adjust how HarfBuzz handles clusters during
178       shaping by setting the
179       <literal>cluster_level</literal> of the
180       buffer. HarfBuzz offers three <emphasis>levels</emphasis> of
181       clustering support for this property:
182     </para>
183     <itemizedlist>
184       <listitem>
185         <para><emphasis>Level 0</emphasis> is the default.
186         </para>
187         <para>
188           The distinguishing feature of level 0 behavior is that, at
189           the beginning of processing the buffer, all code points that
190           are categorized as <emphasis>marks</emphasis>,
191           <emphasis>modifier symbols</emphasis>, or
192           <emphasis>Emoji extended pictographic</emphasis> modifiers,
193           as well as the <emphasis>Zero Width Joiner</emphasis> and
194           <emphasis>Zero Width Non-Joiner</emphasis> code points, are
195           assigned the cluster value of the closest preceding code
196           point from <emphasis>different</emphasis> category.
197         </para>
198         <para>
199           In essence, whenever a base character is followed by a mark
200           character or a sequence of mark characters, those marks are
201           reassigned to the same initial cluster value as the base
202           character. This reassignment is referred to as
203           "merging" the affected clusters. This behavior is based on
204           the Grapheme Cluster Boundary specification in <ulink
205           url="https://www.unicode.org/reports/tr29/#Regex_Definitions">Unicode
206           Technical Report 29</ulink>.
207         </para>
208         <para>
209           This cluster level is suitable for code that likes to use
210           HarfBuzz cluster values as an approximation of the Unicode
211           Grapheme Cluster Boundaries as well.
212         </para>
213         <para>
214           Client programs can specify level 0 behavior for a buffer by
215           setting its <literal>cluster_level</literal> to
216           <literal>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES</literal>. 
217         </para>
218       </listitem>
219       <listitem>
220         <para>
221           <emphasis>Level 1</emphasis> tweaks the old behavior
222           slightly to produce better results. Therefore, level 1
223           clustering is recommended for code that is not required to
224           implement backward compatibility with the old HarfBuzz.
225         </para>
226         <para>
227           <emphasis>Level 1</emphasis> differs from level 0 by not merging the
228           clusters of marks and other modifier code points with the
229           preceding "base" code point's cluster. By preserving the
230           separate cluster values of these marks and modifier code
231           points, script shapers can perform additional operations
232           that might lead to improved results (for example, coloring
233           mark glyphs differently than their base).
234         </para>
235         <para>
236           Client programs can specify level 1 behavior for a buffer by
237           setting its <literal>cluster_level</literal> to
238           <literal>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS</literal>. 
239         </para>
240       </listitem>
241       <listitem>
242         <para>
243           <emphasis>Level 2</emphasis> differs significantly in how it
244           treats cluster values. In level 2, HarfBuzz never merges
245           clusters.
246         </para>
247         <para>
248           This difference can be seen most clearly when HarfBuzz processes
249           ligature substitutions and glyph decompositions. In level 0
250           and level 1, ligatures and glyph decomposition both involve
251           merging clusters; in level 2, neither of these operations
252           triggers a merge.
253         </para>
254         <para>
255           Client programs can specify level 2 behavior for a buffer by
256           setting its <literal>cluster_level</literal> to
257           <literal>HB_BUFFER_CLUSTER_LEVEL_CHARACTERS</literal>. 
258         </para>
259       </listitem>
260     </itemizedlist>
261     <para>
262       As mentioned earlier, client programs using HarfBuzz often
263       assign initial cluster values in a buffer by reusing the indices
264       of the code points in the input text. This gives a sequence of
265       cluster values that is monotonically increasing (for example,
266       0,1,2,3,4).
267     </para>
268     <para>
269       It is not <emphasis>required</emphasis> that the cluster values
270       in a buffer be monotonically increasing. However, if the initial
271       cluster values in a buffer are monotonic and the buffer is
272       configured to use cluster level 0 or 1, then HarfBuzz
273       guarantees that the final cluster values in the shaped buffer
274       will also be monotonic. No such guarantee is made for cluster
275       level 2.
276     </para>
277     <para>
278       In levels 0 and 1, HarfBuzz implements the following conceptual
279       model for cluster values:
280     </para>
281     <itemizedlist spacing="compact">
282       <listitem>
283         <para>
284           If the sequence of input cluster values is monotonic, the
285           sequence of cluster values will remain monotonic.
286         </para>
287       </listitem>
288       <listitem>
289         <para>
290           Each cluster value represents a single cluster.
291         </para>
292       </listitem>
293       <listitem>
294         <para>
295           Each cluster contains one or more glyphs and one or more
296           characters.
297         </para>
298       </listitem>
299     </itemizedlist>
300     <para>
301       In practice, this model offers several benefits. Assuming that
302       the initial cluster values were monotonically increasing
303       and distinct before shaping began, then, in the final output:
304     </para>
305     <itemizedlist spacing="compact">
306       <listitem>
307         <para>
308           All adjacent glyphs having the same final cluster
309           value belong to the same cluster.
310         </para>
311       </listitem>
312       <listitem>
313         <para>
314           Each character belongs to the cluster that has the highest
315           cluster value <emphasis>not larger than</emphasis> its
316           initial cluster value.
317         </para>
318       </listitem>
319     </itemizedlist>
320   </section>
321
322   <section id="a-clustering-example-for-levels-0-and-1">
323     <title>A clustering example for levels 0 and 1</title>
324     <para>
325       The basic shaping operations affect clusters in a predictable
326       manner when using level 0 or level 1: 
327     </para>
328     <itemizedlist>
329       <listitem>
330         <para>
331           When two or more clusters <emphasis>merge</emphasis>, the
332           resulting merged cluster takes as its cluster value the
333           <emphasis>minimum</emphasis> of the incoming cluster values.
334         </para>
335       </listitem>
336       <listitem>
337         <para>
338           When a cluster <emphasis>decomposes</emphasis>, all of the
339           resulting child clusters inherit as their cluster value the
340           cluster value of the parent cluster.
341         </para>
342       </listitem>
343       <listitem>
344         <para>
345           When a character is <emphasis>reordered</emphasis>, the
346           reordered character and all clusters that the character
347           moves past as part of the reordering are merged into one cluster.
348         </para>
349       </listitem>
350     </itemizedlist>
351     <para>
352       The functionality, guarantees, and benefits of level 0 and level
353       1 behavior can be seen with some examples. First, let us examine
354       what happens with cluster values when shaping involves cluster
355       merging with ligatures and decomposition.
356     </para>
357
358     <para>
359       Let's say we start with the following character sequence (top row) and
360       initial cluster values (bottom row):
361     </para>
362     <programlisting>
363       A,B,C,D,E
364       0,1,2,3,4
365     </programlisting>
366     <para>
367       During shaping, HarfBuzz maps these characters to glyphs from
368       the font. For simplicity, let us assume that each character maps
369       to the corresponding, identical-looking glyph:
370     </para>
371     <programlisting>
372       A,B,C,D,E
373       0,1,2,3,4
374     </programlisting>
375     <para>
376       Now if, for example, <literal>B</literal> and <literal>C</literal>
377       form a ligature, then the clusters to which they belong
378       &quot;merge&quot;. This merged cluster takes for its cluster
379       value the minimum of all the cluster values of the clusters that
380       went in to the ligature. In this case, we get:
381     </para>
382     <programlisting>
383       A,BC,D,E
384       0,1 ,3,4
385     </programlisting>
386     <para>
387       because 1 is the minimum of the set {1,2}, which were the
388       cluster values of <literal>B</literal> and
389       <literal>C</literal>. 
390     </para>
391     <para>
392       Next, let us say that the <literal>BC</literal> ligature glyph
393       decomposes into three components, and <literal>D</literal> also
394       decomposes into two components. Whenever a cluster decomposes,
395       its components each inherit the cluster value of their parent: 
396     </para>
397     <programlisting>
398       A,BC0,BC1,BC2,D0,D1,E
399       0,1  ,1  ,1  ,3 ,3 ,4
400     </programlisting>
401     <para>
402       Next, if <literal>BC2</literal> and <literal>D0</literal> form a
403       ligature, then their clusters (cluster values 1 and 3) merge into
404       <literal>min(1,3) = 1</literal>:
405     </para>
406     <programlisting>
407       A,BC0,BC1,BC2D0,D1,E
408       0,1  ,1  ,1    ,1 ,4
409     </programlisting>
410     <para>
411       Note that the entirety of cluster 3 merges into cluster 1, not
412       just the <literal>D0</literal> glyph. This reflects the fact
413       that the cluster <emphasis>must</emphasis> be treated as an
414       indivisible unit.
415     </para>
416     <para>
417       At this point, cluster 1 means: the character sequence
418       <literal>BCD</literal> is represented by glyphs
419       <literal>BC0,BC1,BC2D0,D1</literal> and cannot be broken down any
420       further.
421     </para>
422   </section>
423   <section id="reordering-in-levels-0-and-1">
424     <title>Reordering in levels 0 and 1</title>
425     <para>
426       Another common operation in some shapers is glyph
427       reordering. In order to maintain a monotonic cluster sequence
428       when glyph reordering takes place, HarfBuzz merges the clusters
429       of everything in the reordering sequence.
430     </para>
431     <para>
432       For example, let us again start with the character sequence (top
433       row) and initial cluster values (bottom row):
434     </para>
435     <programlisting>
436       A,B,C,D,E
437       0,1,2,3,4
438     </programlisting>
439     <para>
440       If <literal>D</literal> is reordered to the position immediately
441       before <literal>B</literal>, then HarfBuzz merges the
442       <literal>B</literal>, <literal>C</literal>, and
443       <literal>D</literal> clusters &mdash; all the clusters between
444       the final position of the reordered glyph and its original
445       position. This means that we get:
446     </para>
447     <programlisting>
448       A,D,B,C,E
449       0,1,1,1,4
450     </programlisting>
451     <para>
452       as the final cluster sequence.
453     </para>
454     <para>
455       Merging this many clusters is not ideal, but it is the only
456       sensible way for HarfBuzz to maintain the guarantee that the
457       sequence of cluster values remains monotonic and to retain the
458       true relationship between glyphs and characters.
459     </para>
460   </section>
461   <section id="the-distinction-between-levels-0-and-1">
462     <title>The distinction between levels 0 and 1</title>
463     <para>
464       The preceding examples demonstrate the main effects of using
465       cluster levels 0 and 1. The only difference between the two
466       levels is this: in level 0, at the very beginning of the shaping
467       process, HarfBuzz merges the cluster of each base character
468       with the clusters of all Unicode marks (combining or not) and
469       modifiers that follow it.
470     </para>
471     <para>
472       For example, let us start with the following character sequence
473       (top row) and accompanying initial cluster values (bottom row):
474     </para>
475     <programlisting>
476       A,acute,B
477       0,1    ,2
478     </programlisting>
479     <para>
480       The <literal>acute</literal> is a Unicode mark. If HarfBuzz is
481       using cluster level 0 on this sequence, then the
482       <literal>A</literal> and <literal>acute</literal> clusters will
483       merge, and the result will become:
484     </para>
485     <programlisting>
486       A,acute,B
487       0,0    ,2
488     </programlisting>
489     <para>
490       This merger is performed before any other script-shaping
491       steps.
492     </para>
493     <para>
494       This initial cluster merging is the default behavior of the
495       Windows shaping engine, and the old HarfBuzz codebase copied
496       that behavior to maintain compatibility. Consequently, it has
497       remained the default behavior in the new HarfBuzz codebase.
498     </para>
499     <para>
500       But this initial cluster-merging behavior makes it impossible
501       for client programs to implement some features (such as to
502       color diacritic marks differently from their base
503       characters). That is why, in level 1, HarfBuzz does not perform
504       the initial merging step.
505     </para>
506     <para>
507       For client programs that rely on HarfBuzz cluster values to
508       perform cursor positioning, level 0 is more convenient. But
509       relying on cluster boundaries for cursor positioning is wrong: cursor
510       positions should be determined based on Unicode grapheme
511       boundaries, not on shaping-cluster boundaries. As such, using
512       level 1 clustering behavior is recommended. 
513     </para>
514     <para>
515       One final facet of levels 0 and 1 is worth noting. HarfBuzz
516       currently does not allow any
517       <emphasis>multiple-substitution</emphasis> GSUB lookups to 
518       replace a glyph with zero glyphs (in other words, to delete a
519       glyph).
520     </para>
521     <para>
522       But, in some other situations, glyphs can be deleted. In
523       those cases, if the glyph being deleted is the last glyph of its
524       cluster, HarfBuzz makes sure to merge the deleted glyph's
525       cluster with a neighboring cluster.
526     </para>
527     <para>
528       This is done primarily to make sure that the starting cluster of the
529       text always has the cluster index pointing to the start of the text
530       for the run; more than one client program currently relies on this
531       guarantee.
532     </para>
533     <para>
534       Incidentally, Apple's CoreText does something different to
535       maintain the same promise: it inserts a glyph with id 65535 at
536       the beginning of the glyph string if the glyph corresponding to
537       the first character in the run was deleted. HarfBuzz might do
538       something similar in the future.
539     </para>
540   </section>
541   <section id="level-2">
542     <title>Level 2</title>
543     <para>
544       HarfBuzz's level 2 cluster behavior uses a significantly
545       different model than that of level 0 and level 1.
546     </para>
547     <para>
548       The level 2 behavior is easy to describe, but it may be
549       difficult to understand in practical terms. In brief, level 2 
550       performs no merging of clusters whatsoever.
551     </para>
552     <para>
553       This means that there is no initial base-and-mark merging step
554       (as is done in level 0), and it means that reordering moves and
555       ligature substitutions do not trigger a cluster merge.
556     </para>
557     <para>
558       Only one shaping operation directly affects clusters when using
559       level 2:
560     </para>
561     <itemizedlist>
562       <listitem>
563         <para>
564           When a cluster <emphasis>decomposes</emphasis>, all of the
565           resulting child clusters inherit as their cluster value the
566           cluster value of the parent cluster.
567         </para>
568       </listitem>
569     </itemizedlist>
570     <para>
571       When glyphs do form a ligature (or when some other feature
572       substitutes multiple glyphs with one glyph) the cluster value
573       of the first glyph is retained as the cluster value for the
574       resulting ligature.
575     </para>
576     <para>
577       This occurrence sounds similar to a cluster merge, but it is
578       different. In particular, no subsequent characters &mdash;
579       including marks and modifiers &mdash; are affected. They retain
580       their previous cluster values. 
581     </para>
582     <para>
583       Level 2 cluster behavior is ultimately less complex than level 0
584       or level 1, but there are several cases for which processing
585       cluster values produced at level 2 may be tricky. 
586     </para>
587     <section id="ligatures-with-combining-marks-in-level-2">
588       <title>Ligatures with combining marks in level 2</title>
589       <para>
590         The first example of how HarfBuzz's level 2 cluster behavior
591         can be tricky is when the text to be shaped includes combining
592         marks attached to ligatures.
593       </para>
594       <para>
595         Let us start with an input sequence with the following
596         characters (top row) and initial cluster values (bottom row):
597       </para>
598       <programlisting>
599         A,acute,B,breve,C,circumflex
600         0,1    ,2,3    ,4,5
601       </programlisting>
602       <para>
603         If the sequence <literal>A,B,C</literal> forms a ligature,
604         then these are the cluster values HarfBuzz will return under
605         the various cluster levels:
606       </para>
607       <para>
608         Level 0:
609       </para>
610       <programlisting>
611         ABC,acute,breve,circumflex
612         0  ,0    ,0    ,0
613       </programlisting>
614       <para>
615         Level 1:
616       </para>
617       <programlisting>
618         ABC,acute,breve,circumflex
619         0  ,0    ,0    ,5
620       </programlisting>
621       <para>
622         Level 2:
623       </para>
624       <programlisting>
625         ABC,acute,breve,circumflex
626         0  ,1    ,3    ,5
627       </programlisting>
628       <para>
629         Making sense of the level 2 result is the hardest for a client
630         program, because there is nothing in the cluster values that
631         indicates that <literal>B</literal> and <literal>C</literal>
632         formed a ligature with <literal>A</literal>.
633       </para>
634       <para>
635         In contrast, the "merged" cluster values of the mark glyphs
636         that are seen in the level 0 and level 1 output are evidence
637         that a ligature substitution took place. 
638       </para>
639     </section>
640     <section id="reordering-in-level-2">
641       <title>Reordering in level 2</title>
642       <para>
643         Another example of how HarfBuzz's level 2 cluster behavior
644         can be tricky is when glyphs reorder. Consider an input sequence
645         with the following characters (top row) and initial cluster
646         values (bottom row):
647       </para>
648       <programlisting>
649         A,B,C,D,E
650         0,1,2,3,4
651       </programlisting>
652       <para>
653         Now imagine <literal>D</literal> moves before
654         <literal>B</literal> in a reordering operation. The cluster
655         values will then be:
656       </para>
657       <programlisting>
658         A,D,B,C,E
659         0,3,1,2,4
660       </programlisting>
661       <para>
662         Next, if <literal>D</literal> forms a ligature with
663         <literal>B</literal>, the output is:
664       </para>
665       <programlisting>
666         A,DB,C,E
667         0,3 ,2,4
668       </programlisting>
669       <para>
670         However, in a different scenario, in which the shaping rules
671         of the script instead caused <literal>A</literal> and
672         <literal>B</literal> to form a ligature
673         <emphasis>before</emphasis> the <literal>D</literal> reordered, the
674         result would be:
675       </para>
676       <programlisting>
677         AB,D,C,E
678         0 ,3,2,4   
679       </programlisting>
680       <para>
681         There is no way for a client program to differentiate between
682         these two scenarios based on the cluster values
683         alone. Consequently, client programs that use level 2 might
684         need to undertake additional work in order to manage cursor
685         positioning, text attributes, or other desired features.
686       </para>
687     </section>
688     <section id="other-considerations-in-level-2">
689       <title>Other considerations in level 2</title>
690       <para>
691         There may be other problems encountered with ligatures under
692         level 2, such as if the direction of the text is forced to
693         the opposite of its natural direction (for example, Arabic text
694         that is forced into left-to-right directionality). But,
695         generally speaking, these other scenarios are minor corner
696         cases that are too obscure for most client programs to need to
697         worry about.
698       </para>
699     </section>
700   </section>
701 </chapter>