From fb333d890be38583c1fbac5f2940dd366eb1722b Mon Sep 17 00:00:00 2001
From: Matt Bovel <matthieu@bovel.net>
Date: Wed, 30 Mar 2022 14:50:09 +0200
Subject: [PATCH] Add instructions for lab 6

---
 README.md                                 |   1 +
 labs/lab6-lock-free-sorted-list/README.md | 191 ++++++++++++++++++++++
 labs/lab6-lock-free-sorted-list/step0.png | Bin 0 -> 2042 bytes
 labs/lab6-lock-free-sorted-list/step1.png | Bin 0 -> 4278 bytes
 labs/lab6-lock-free-sorted-list/step2.png | Bin 0 -> 6487 bytes
 labs/lab6-lock-free-sorted-list/step3.png | Bin 0 -> 7112 bytes
 6 files changed, 192 insertions(+)
 create mode 100644 labs/lab6-lock-free-sorted-list/README.md
 create mode 100644 labs/lab6-lock-free-sorted-list/step0.png
 create mode 100644 labs/lab6-lock-free-sorted-list/step1.png
 create mode 100644 labs/lab6-lock-free-sorted-list/step2.png
 create mode 100644 labs/lab6-lock-free-sorted-list/step3.png

diff --git a/README.md b/README.md
index e6cedbb..21fdb61 100644
--- a/README.md
+++ b/README.md
@@ -105,6 +105,7 @@ Labs are submitted by pushing your code on GitLab, see details in the [grading a
 | Lab 3 | K-Means                    | 2022.03.09  | 2022.03.20  |
 | Lab 4 | Barnes-Hut Simulation      | 2022.03.16  | 2022.03.27  |
 | Lab 5 | Concurrent Bounded Buffer  | 2022.03.23  | 2022.04.03  |
+| Lab 6 | Lock-free sorted list      | 2022.03.30  | 2022.04.10  |
 
 # Exercises
 
diff --git a/labs/lab6-lock-free-sorted-list/README.md b/labs/lab6-lock-free-sorted-list/README.md
new file mode 100644
index 0000000..492be39
--- /dev/null
+++ b/labs/lab6-lock-free-sorted-list/README.md
@@ -0,0 +1,191 @@
+# Lock-free Sorted List
+
+Use the following commands to make a fresh clone of your repository:
+
+```
+git clone -b lockfree git@gitlab.epfl.ch:lamp/student-repositories-s22/cs206-GASPAR.git cs206-lockfree
+```
+
+## Useful links
+
+  * [The API documentation of the Scala standard library](https://www.scala-lang.org/files/archive/api/2.13.4)
+  * [The API documentation of the Java standard library](https://docs.oracle.com/en/java/javase/15/docs/api/index.html)
+
+**If you have issues with the IDE, try [reimporting the
+build](https://gitlab.epfl.ch/lamp/cs206/-/blob/master/labs/example-lab.md#ide-features-like-type-on-hover-or-go-to-definition-do-not-work),
+if you still have problems, use `compile` in sbt instead.**
+
+## Introduction
+
+The goal of this assignment is to implement a concurrent list that stores values of type `Int` in ascending order.
+Last week, we have seen how to use a monitor to make data structures operations behave correctly in a concurrent setting.
+This week, the data structure we will implement will not use a monitor or a lock of any kind.
+Instead, we will use an atomic operation, called `compareAndSet`, in your implementation of the data structure operations.
+
+The goal will still be to have a data structure that can safely be used in a concurrent setting.
+In addition, the sorted list operations you will implement will be *lock-free*.
+In a system where all concurrent operations have this property, the progress of at least one thread is ***guaranteed***.
+There can not be a global deadlock in which none of the thread can make progress!
+Note that this does *not* guarantee that all threads can make progress.
+Operation with this property is said to be *wait-free*.
+
+## Atomic Variables
+
+The list methods you will implement will make use of atomic variables. An atomic variable is an object which holds a value of a given type `T`. The object offers two methods to manipulate this value:
+- `get`, which returns the current value held in the variable,
+- `compareAndSet`, which modifies the content of the variable provided that the previous value is given. This method returns `true` if it was successful, `false` otherwise.
+
+The operation `compareAndSet` applies the following logic ***atomically***, which means there cannot be any context switches between the instructions of the operation:
+```scala
+def compareAndSet(expected: T, value: T):
+    if current == expected then
+        current = value
+        true
+    else
+        false
+```
+
+The `AtomicVariable` class is given to you. You do not have to worry about implementing it!
+
+Note that a similar class exists in the Java standard library, called [`AtomicReference`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html).
+The main difference between `AtomicReference` and the `AtomicVariable` class we defined for this exercise is that `AtomicReference` uses referential equality to check whether `expected` and `current` are the same, while `AtomicVariable` uses the `==` method.
+
+## The Sorted List Data Structure
+
+The data structure you will implement is a mutable linked list of integers, sorted in ascending order. Each integer is stored in a `Node`. In addition to the integer value, each node contains a mutable reference to the next node in the list. This mutable reference is held in an `AtomicVariable`.
+
+```scala
+abstract class Node(val value: Int, initTail: Option[Node]):
+
+  type State = Option[Node]
+
+  def initialState: State = initTail
+
+  val atomicState: AbstractAtomicVariable[State] = new AtomicVariable[State](initialState)
+
+  def next: Option[Node] = atomicState.get
+
+  // ...
+```
+
+Then, `SortedList` is simply a class that holds a reference to the first node of the list. This class is defined in `SortedList.scala`.
+
+```scala
+class SortedList extends AbstractSortedList:
+
+  // The sentinel node at the head.
+  private val _head = createNode(0, None, isHead=true)
+
+  // The first logical node is referenced by the head.
+  def firstNode: Option[Node] = _head.next
+
+  def findNodeWithPrev(pred: Int => Boolean): (Node, Option[Node]) = ???
+
+  def insert(e: Int): Unit = ???
+
+  def contains(e: Int): Boolean = ???
+
+  def delete(e: Int): Boolean = ???
+```
+
+The value `_head` of the list is called a [*sentinel* node](https://en.wikipedia.org/wiki/Sentinel_node). This value is simply `Node` that will serve only as a reference to the first actual node of the list. The value (viz. zero) held by this special node should be completely ignored. This technique is useful because it limits the duplication of code. An alternative is to have a reference to the first node using an `AtomicVariable`. But this would force us to handle the first node differently from the rest. So will use a sentinel node for this assignment.
+
+### `findNodeWithPrev`
+
+The first method you will implement is an internal helper method which will be used all other methods.
+This method should do a traversal of the list to find the first node whose value satisfies the parameter predicate.
+The method should return the following two values as a pair:
+- the predecessor of the node,
+- the node.
+
+If `node` is the first node whose value satisfies the predicate and `predecessor` its predecessor, then the method should return `(predecessor, Some(node))`. Due to the use of the sentinel node at the head of the list, the method is bound to find a predecessor, even for the first logical node.
+
+When the predicate doesn't hold on any of the values, then the function should return `(last, None)`, where
+`last` is the last node of the list.
+
+### `insert`
+
+Your first goal will be to code the insert method of the lock-free list. The idea is very simple:
+
+1. Locate the position you need to insert by using the `findNodeWithPrev` method you have just implemented.
+2. Create a new node that holds the value and points to the correct next node. For this, you should use `createNode(value, nextNode)`.
+3. Use the `compareAndSet` operation to make the previous node point to your newly created node.
+4. If the operation failed, retry from the start! Otherwise, the operation is done!
+
+### `contains`
+
+Next, you should implement the `contains` method, which checks if the list contains a given element. You may of course use the `findNodeWithPrev` method you have implemented.
+
+### `delete`
+
+With the addition of `delete`, things get rapidly trickier. The intuitive solution would be to:
+
+1. Find the node to delete and its predecessor using `findNodeWithPrev`.
+2. Use an atomic `compareAndSet` operation to make the predecessor node point to the successor.
+
+Unfortunately, this solution is not entirely satisfactory!
+Indeed, there exist schedules in which some successful operations are lost. Can you think of any?
+
+As an example, assume that the list currently contains the values `10` and `30`.
+![Step 0](step0.png "Initial configuration")
+
+- Imagine one thread starts executing the insertion of `20` in the list and correctly locates where to insert the new node (between `10` and `30`). The thread then creates a node with value `20` and makes it point to the node with value `30`.
+
+  ![Step 1](step1.png "Right in the middle of inserting 20")
+- Now, some other thread is scheduled and starts executing the deletion of the node with value `10`. The thread finds the two nodes that surround it, that is the sentinel node at the head of the list and the node with value `30` (note that the insertion of `20` by the other thread isn't visible yet!). The thread, using compare and set, changes the next pointer of the sentinel node to the node with value `30`. The `delete` operation then terminates successfully.
+
+  ![Step 2](step2.png "After the deletion of 10")
+- Now, the first thread resumes its execution. Its next instruction is to use compare and set to change the next pointer of the node with value `10`, which it can do without any problem! Indeed, this atomic variable wasn't touched by the delete operation. The `insert` operation looks successful, even though the node that was inserted is not reachable from the head of the list! The operation was lost... ![Step 3](step3.png "Final configuration")
+
+One solution to this problem, as proposed by Timothy L. Harris in his paper [A Pragmatic Implementation of Non-Blocking Linked Lists](https://www.cl.cam.ac.uk/research/srg/netos/papers/2001-caslists.pdf), is to somehow record in the node that it was deleted.
+We will proceed similarly in this assignment.
+
+#### Marking Nodes
+
+The first step is to modify the mutable state held by nodes. Open the `Node.scala` file. Until now the state was just `Option[Node]`, which is an optional reference to the next node.
+You will need to add, in addition to this information, a boolean flag that indicates whether the node was deleted or not.
+
+
+```scala
+abstract class Node(val value: Int, initTail: Option[Node]):
+
+  type State = ???
+
+  def initialState: State = ???
+
+  val atomicState: AbstractAtomicVariable[State] = new AtomicVariable[State](initialState)
+
+  def next: Option[Node] = ???
+
+  def deleted: Boolean = ???
+
+  def mark: Boolean = ???
+```
+
+Begin by modifying the `State` type to any type that you deem appropriate. Remember that the value of this type should contain an `Option[Node]` (the next node) and a flag (whether the node has been marked).
+
+Complete the other functions, described below, as well:
+- `initialState` should return the state of the node when it is first created. Note that the node should not be marked and the optional reference to the next node should be set to `initTail`.
+- `next` should return the optional reference to the next node held currently in the state.
+- `deleted` should return `true` if the node was marked, `false` otherwise.
+- `mark` should mark the node as `deleted`. The method should return `true` only if it is the first time this node is marked. If the node was previously marked, this method should return `false`. (Think carefully about this!)
+
+#### Implementing `delete` of `SortedList`
+
+Now, we can implement a version of delete that is not vulnerable to the problem exposed earlier. The idea is to:
+
+1. Find the node to delete and its predecessor using `findNodeWithPrev`.
+2. Mark the node as `deleted` using its `mark` method. If it returns false, retry from the start!
+
+Once this is done, we still have to modify the other list methods to handle the fact that nodes can be marked.
+Marked nodes will be deleted within the `findNodeWithPrev` method.
+
+#### Adapting `findNodeWithPrev` to handle marked nodes
+
+The first method you need to adapt is `findNodeWithPrev`. The method should do exactly as before except when it encounters a marked node during its traversal. When it does so, the method should use compare and set to modify the next node pointed by the predecessor node. Regardless of the outcome of the compare and set operation, the `findNodeWithPrev` should then restart from scratch.
+
+#### Adapting `insert` to handle marked nodes
+
+The last method you need to change is `insert`. The logic remains exactly the same, except that when you perform the `compareAndSet` operation, you should make sure that the parameters are of type `State` and are not flagged as deleted.
+
+You are now done with this assignment. Congratulations!
diff --git a/labs/lab6-lock-free-sorted-list/step0.png b/labs/lab6-lock-free-sorted-list/step0.png
new file mode 100644
index 0000000000000000000000000000000000000000..7730e289490798d2a298b3794e592fd810a81df3
GIT binary patch
literal 2042
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
J);T3K0RVv$JpBLw

literal 0
HcmV?d00001

diff --git a/labs/lab6-lock-free-sorted-list/step1.png b/labs/lab6-lock-free-sorted-list/step1.png
new file mode 100644
index 0000000000000000000000000000000000000000..59a5df13ab342a8965fff748ab716d17365d28b4
GIT binary patch
literal 4278
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
AoB#j-

literal 0
HcmV?d00001

diff --git a/labs/lab6-lock-free-sorted-list/step2.png b/labs/lab6-lock-free-sorted-list/step2.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b09129d815cdbc2081ca7d9073c9c18cb6d0a90
GIT binary patch
literal 6487
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

literal 0
HcmV?d00001

diff --git a/labs/lab6-lock-free-sorted-list/step3.png b/labs/lab6-lock-free-sorted-list/step3.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb9dcfff4ac0a5ecbe3cbee823a1793b03e7c0d9
GIT binary patch
literal 7112
zcmeAS@N?(olHy`uVBq!ia0y~yVEn?sz$nYX#K6E%`k!e!1A}zGr;B4q#jUq<>oXRA
z{d-`2%z5sb)oE)yjyy72>wd%P<j!58Ya{xLLc|QR4)&ey%Q>c-B~cn4VRq_OkHEs&
zfuG$aLpM*{SkN}nDZgc6@1noTXMBt`c7Hh$G2zrF_mr99?@vwJ{rUI2`R~6kT(<xA
zmfCsh>#xfve}Cfn=ga3k_UoVj{b@7*`De>7oD2*z`kX@;85oM#85o}MF)*BvWnh?K
z&A^~gj>&g;hbj-^H{4-lVA#nFR*%dF8HmJ}(YcznHA3gy`Sa?NPe$md{n!4#KSWDc
zS2xhI;SS@MjNHN!z3Hb@j6PP_NcH;p`26@=xBd3r`}gnPy_>uJwyxOeg}g6cy_$6S
z$)AZ6Ctkc5__NhRWs--=vuDqqOy9}KP{f{LH`PmZ_Svo-haYa3asBnzT`_us8xKEx
z@#c-q7Rj*Hp(6Uv`T6;O*X;ZFv9R#_lP6DZ+?es_%7X_B{+tWTV|e@a?JG6|6B7{*
zmM88@*cHC%Pd^=_?C_3Zc7Tr9<(FGdgm20>T>0cm($%jy*_&@xRaLREu}#_0d~iWc
z;2djf>)Gd@t1e!D{q^lvEFxU2AGeA))TxMYc}hN+{`C7?zvX|nU;Di8PVy5O&4wqx
zKgIrhUnI-8)A{wLJ$vSyej2oLO3GzrW#vVgCpU#ZzdK2@J7w|36)Nv%`nc^=`nKk3
z7JJaMrAt+J=APhHnCRi->+AVT|1QVL7t&pKFJ8QO`?hxdlsk$~_@`7K+m>g{a6*>H
zd1s86dY1rmW5eyYamIr0-n|o>+HLsM#4_?t{sQT#9`QZ)hK39CLU?8QelC}pVjr_h
zylDEQ=qrwQ=QHeNeq(l0wA(XG&n;Tl`ed%_Q?Ig(5jly83!~P~dU<|&$leGYuUm3_
z?R(?at9<&TZhq&C%G2qyZ@zf3;?5bB-Rfx!JDb<dmFsl*_3KyItvgv;yY3z-To~ZN
z+aax?ouBtzb@EA%zd!!|Yiw+6V?R{nq7%O|q(jN!-Gcb#)^pEwc5*(OoYV6qeACS}
zDc^%)qpqIp4bYlg#r%ZtSJAE&t0HuQEUj1gth6%R9X9jt-@hSh3gri0F59$cMy&Kk
zNg0_rbLKoL)pB^(aQUpm!hi`}(_`wM?${%fsAUUMm$o2A&-}@!BF<&YmhE6^xWl-7
zHsi{gsi(8WUG)MqM3RoMO|Z_Hr{d@5_o(FW{i>rci)L<#iThNg!+%2dn!@a}ziRAq
zId$jcad<5aGLgD^?CH~KZ@yNEi;1m}ba=PcZ*QEx+GJ*C=3CtEiz?>i9nqV9|NZrA
z&n2a#PNf)ya2K_QEs0v|<sKLP-D}hSmoHylt0})?a^mUaZjHTqxjW}Y=o~Y3eRo02
zBS|lEUe(`Nt512`qc_=v>6r-M%qgp=h_JQTcr&L+-2CP%+lD(2jnAAtyE8`b>N8!j
z?&FUWFKy}66ydrR(Hrw_<3_`_#}ln*aGg9AymHF5==ZN)&6+buWoowI6DRk@f$fJE
z?&X~7qqb7)313>qjiln-LorGd69lH!&AyvAUD~EQK&jk7?q`ji0LO~dBTH?)S5MpK
zyY;}KLrupYUu=8!r_O%z;tAFg%_UZE%XV+QW^HA4Do)_SflHSrv9xV#<@jFrgzuND
zZ}a7Q=^Jn6@T@s}>`K<wsqY=We);0Tv5{4wh<&dDo4mC2<+5)tU%yT+GtTMuQCrM=
zJbLZ51Otz#hC2@%1p8P2UA8opkDvc}k>x9vvSX(nR-6=7n#hrFuTXBmu<7QSD7LVu
zWCekQiy9eRLLNeXULW`F-MfVQgzUHepp{R)R)v0+mXLUGR^&#vPF!@MM^o<=#+`@n
zZQ8TP#?Ww~nx%zIpNo>?+ynO}`lwyqoi9`*RAH0t`fh{zlAx9E-sPDdG?d}{d_v?~
zW7S@{PL~k7#O=4!)6-W9KjHIT9HGO<&%fI4(}@!twJA5!Pd(jaCiJ3c=ck`GrA>Dd
z!#&(9N=icBF1&dE{`|9PD}^mI!t4%z|NS?q<`v7%!+suWle6}gK3m#YHz6QIKlDb<
zwh9}+2&M8HY{kXJQC%uCt@EceteemvBQGDm*u-!7<fYsbtaJR927UZl!;{zaFESz`
zK(j-^@w5hSQG4mkIdejywM)v&H@`5GXu5eb(zMgt$y}<}$gBCzL*taqkz4B~A5G$H
zb=o3eARx3(JAQw{6t<m*|9{QhYC8MIcfOv}mo8m8aiT+Nsid4-+RTb4_jc*%>$5jI
znx4J*vLww&@)b)@-;%eswzjMIPkFCBvDfu>gIUnY8Y2VAP8X-#cNyDnKY#vwrNEPW
zPMo`?+CNt9^(kfvR<f*C5C~XolAN5pW?JJNUq7?ip>xA#pFLJ1VPN~RBx>o0Oa7@}
z6Q1PxUFl&GD$6icxl(I4ze?GE7K8GH6L&*IxLBudC@(3Qu)&#olGoBJi&*`ZPY(Y)
zVYeqo`{69E4Y%K>Il5;=YEA8mx)T!g<K#)tpo%AXZ(3sa&Oggx-JmqlW5x9i)z#HY
z8v_(i+^z8O^<CLgTTn0|)ttd(iRF$MJyUTzsoo&P6L$@!c&Q5Rnsr#OYx!@^4YMM2
zmTj8f*vJ@n#_gROSL8`wj>v}I%L-e0x0^_2T7+;EUC&Q1&dBg6HLHwc+2Fe9;)<vi
z=UM#5d=qxR^H7^?Hruy%!{-?s3DF|mNB8ZsGo3WkLuG})lXcu%IO8VO8XV%=ki2C7
z>U*Civ#Fl#;&Ob)e)7(pIaRx(KJ~S>vTCs;m_PYkx%~3VZ@hj>gKq!QyM0{w`!fZ}
zUpH<<{9gVc$kahN`Wm0uD}l}4*Jsu`P57NR(WA&hChNYWP+7yW$)}%&2yecbGg~V<
zkKxsmg$or|@$Gysz^OcSgSQH6v*R}<h8vg9ZHzLp5a3vI{o1tY)34Tev0j#(@Y`>K
zN-QtOt+!=neoQympFMxRbmz*rPqVc9D)-)V)}BxwlzF1|w&SvCTVKC_pMEf|q1L&m
zEVbaJp})WX`ad53Dqn1l&=FHRt^7S#pwnfGy3HF+<_-UsT+aNe)%k7RWR*{^azC&&
z9aOm5dS`pftt<zlrV1OsTm~7Dsa~#YE!6z}pUtmZoTj+mZI)JT_LF^_LQ1!0?LD)J
z=>qe^f(YI44U7u|I=Y<Ry<TK%_xA1ER89kizYFeh-e>T9HS=WKo$G27JyslFZa2T*
zv5eubK&J~|E+bpu#NSdZ&5mDRX<BnKyyybui>-;lGJNjc`_23A*f*CvwUOg*e#2n3
zBtmDE?yqep{`|2iYX2X!Hmth3T2-y8s!Ae-{X+ETkn;z&^__m|^zMVF+T@GZ%2Rd*
zGVEQb=9o7<EbbTQ&i~URbe6Gwa&vdDtl?T<?zHg2LfMC(e@>|G4qAQn$*1m{x?<eB
zEtp<Ra8cTLw0*_uiTcw{r#`t?l+pag#*XzuG21l1<*JqCyYJqvTChq&TH5*DT35UI
z*V%4Hf4j$*V9|ASQOTyIhjnM(T(*AIs@lltV$-IyQ?-SKg||37EQ420iE26V{=4ys
zb^bhpenB4Vt{hbRdg(b|`(eH5*?X6!waEW@!0r|}+3)GTs-M2KMURefnzpF_HQjdn
zvThs4@;1?ohY6Zfy*gczYHDJ3J=Si2Y5#rac}XYVv%Jfno&Njf<>g&_4ZUt|DScdF
zeN&+5dalLF2&Z?uTt98gF|)R`eEG4$?*Gs8(oVir(|6B196L22?{Q8|mdMW6W^=yC
zzfG_(Rs4Q;+J~v(af){`C!ClY;q>l`Lczuk)g;cH%H<C44jgrQ7nAJpuHnu^Yu-t0
zo*x-Z70abmcqc_DO`BkC$`PZJ)Ctz3P!48*)PnSwcu1)fv0rJqlR3e}ql<k7=T2sH
zJtt%*SQl)ZV0~R;g0({V6TjvqjzKmKzQ-n4zX-l|XX7vb`d^c4zO0V_+r{SDe5c{)
z(WCKy9*N)o^US>d_wD<61yOp_t&5+Xxm$k!?}x+u?n)E;?f=b)P?~1)>F1yG_5X_3
zU%!3(_UjU>{U3Yt_k22~{hIZpUh>M&C+oHytp0wtJiK0ItD5}X`u~4V%w^lDb}-??
zv)TFgPW4TBer~RH)t8Lw>fd|6->ZJTcKfN5-|v>+cbBhq(Gm3SdSCP0`qNbFcRL<G
zIXSs(cdYA`>HEGcjaqx{ON7%qkWrkI;&$GBH$A>CGU__p{i!dkik_VCHNP98HTB9w
z@%Wm+bMi7WD$_btkIMi1(7ylg+x%Ph=jYqk|NVOXbia?EpPB8n3D!l+9rLET%T=Z{
zzn^DS>SbqJ{q4=EW})z+fM3^-2yNV=cK`Ri?@!!q<oquugCa^QMfgda-gMQglj=$i
zA6U_~u5FpOj-a>H!-9yqC%^CiuR|!C=cD#?@xOon+8+O`iR-&xbXpf=;H;{>_pV>R
ze(l;eBl-L=9Ys)l<TTxhuX?Ha^TkDX`CN;C2ifIMd_3IF?`^C$twXifd%E7<uh*iT
zot-Bw+5hcUcD11QTGjIIqo3?o?|8TC^#p6)qUlBT-)^QqU93K@V$s7NPft$|eY5xf
zzu!lMHmdyjb$x#re_*SA%|q_`pQq!$X-tdqe#gwr{4TWSsdl{MJChT!r~aN)pFgF4
zUgfiyZI8p(#RP6F|M#adsWU?8$TR!DFa76Ny;>=(?zd&@R?lNUC(r-m@@UD+jYl@{
z95ymJp?2c$&gb(c_xsJYx>~R&Xyu9<w;%DOCarW$^4z#%$BJhg{=aay&#FRrwEl1D
z&ld~Z<+3d59v)(~)Vo`d)EN;qxx`A>zUXf0^}oOG|If>VE5Bd&JNM^{ZMXBXE$obq
zm5;yQ^;!?CK5Of$Hz67#v!uOG$nLzXFk9h!_VsnL)@43+Q~SQ1dTck}pU-V^AXsVA
z#uaZ=rsX3HZ4HmF-I_S5dCP6-{5>Drr1N%Ed{o-#qO-QM%K7TU0uxxmXxg&Hcz)4w
z+42+R{_|{B{+oF+C2U^V&reU;<!b``Dt^6O{`}dqdlip)PwwZFx0C5V-l>}8S@`Hk
z=li<vyYu(`d^Z38pXbHT&)I&vk(~AFS9Jc~tMIh@{Z8@ug<C8B{d_KcZcoX}NvEG?
zWoHMgN30FYJO)Z9jyiWMpU>U@|L^<o`8$6{{AxLC6}7Ns!+i1AhxzU2%$!;Ie((2n
zaeKXV1ig9xe4hXR%+sRu^Yi}ReP37p@K9@SbBg)K7I0DWh%w9Q9jKJp$Z}$?6pNnN
zMi(8$@+^S~)?mguLxu7ONuZ)eq1?gu#9TJd<|P#kvnGHGAss<)Bt1{~PRQ<vI59Vy
z2STGNWh`3G*4XU|)$+s-%z!9moBsRd<>kx2c1`JJ%Ur{@@^-<mYuopMlvafWe}1~I
zK4St~)`TNM3zjuc|NZFEqb-6HiiF<%azFp@%H6xVz8@Re<$k=5|9@&~*1?FXKfxvI
zmN~~%G`!ukXV04wtE2DZ)=$5cVanCobTmm)O6pRj<wWZPej3wH+uGVb`u_1_Vb<c(
z6<4$P+MU<!{t^4nzKGpm`TeUue00PXn?<p_T%GCs#A^S$6S4`<b#!z}%F4W~{naL4
zX?r<w^__e7)}4%fu55flHX%G^bL8peXU?4ql2%L0%siR4dF`A#N{g<4KEYGOenWSr
zkJ}SHU)#BU!P052pT1n3EdI5|-TfVd@9PcGYp>PV`RC5)@9gX}O<z`RBlm<ap=jB%
zWlOe}mzGZTQq4N-ld}2dROh$aFJHV^5w`k-?13jOPKucy{FZNy(F>M-wjgZvO3T34
zhUVt&cNow38%RuHdtYFoHI-{?B2(D8+L*}~F9ts0yCC$V#xC<SGc)t))2FYrE%aO(
z^qTiXMoDSu)z_s@_!8=ttXw@)^jE#Jtl5G9jfl0^*6RFNdVZqh6TS;ISzB*Cc(A~v
zdjEa@T!}AycduXHe)Ou0x|-SqYlqbVYs0QSN;;SjF#m4ZjfSt!?ACQ2e(3OyLHEd|
zOOx*Ah1V@N<2k}sEPvg({k^$Dd4uhe01b`({=U9}(rpgW-wUH(eE8RUhw+<OZsA53
zCCA(s^4o9kZT6k=>({Rd)()o)?d|pJwnymfs(r{Rvis%)|NMM4<?@EV31wy5_U?`S
zbM8@6)v^GMBac6Jc5<%2{<_3!yXhx6zV?aM4%$N9M_t5ZWo389^xZOG`C1kG>7$RD
zaHorn-1&*h?mQ+&&372T@fWgmcS}zB`Li<hL)O++CGtFMck{N#_^Ot_oc1#7Eawxx
z4eNXQ`@1>blv#J5m*75m=X$l4-t<iY8Y+`dCT;Av!x$yL|NeTh{v+?*7KW|fx_x_j
zS((&}T9YSy1q?ksJuB?&y1ONtDs1$wpML&Xa>bbwvJV&pmhX<y`*`%h1BGtk7xG)r
zojG)fsffMd?B8`$9)7J_$!k0LY}!+!uV21MtiEwV_Q3&->8Ew{mepTj)46>4@(Edn
zZCu^mFZVZJ{i)ejZPj##k#C06!i3E?BVv5!FA37LeZRE*4r7V0-Te12UI=s^N!qwp
z<@c^x{<(QqmT7<f{P~0|Lz$D++-(s$Z{NO^*4I<p&gl7BU0r?U##)DWi;G-;{r=q>
zQSpRtfw<Ako+t0aR+sKQntp{d>wE61Z25rShOUbPpYSp4R+8&qZLS!uZ>KD;xmi1F
ztJKx4%dfmH-F;W@`>m|4U3VB0wy#h<>Z+~He(mtXg2SISZ{EE5%GG(3JXDs<vz6<2
zJl%hXv7~)PjILay-gNt)|0}QYvM@1fW%&p82L-PbDPnI}wot79&!_48|C~_nU$e7n
z$C7V*zHcdC;l8qMUCI-_1;KLFZw!;)zD`ry6Sw~2eI4g_3{^|QR?oGmycF?!*UYvO
ztF@QPob9)|y<@175q|OZ?cI{g=N2whe6{N3l+&rR&!%mR`1Etn!v6wK_!j7UEu9pV
zn-=Wipu>JY=GE7#`uhErRjwyw9o$nk-#mBjoO86=<dXrJzA7SIEA=LF%7rPHGwfXu
zreLu}c80)Bm!h3>uIxXX7Hk|a(VD@evBG9w>}KggcFwy&D?@he+QqZWO`?eX!up%i
zaSnH_j@|n0yM4#qyp?A*ZZy372V{%*lg~dL6gD(JnH&0`++Rm*@~k)S-<w}%&U(VP
zKsjsctuJ4`95`^`+S7MMJ6CLvy%)ANEZg0^{bbll_je3cE-uQQf5Otvb<CI{uygkA
z%<}T>A<0S;4Q|eFyTka!dvDzQxpQUZ<nC3t*v<6|4!3rGw;-r7ZvFL|dZ{9I1BRtR
znj%~)Wr|I6*6lT(baKfZ)46`jHFw*ckUij$vN>}9{ryGP`L;T#m~M{cYHhljCAw3(
zb|&K!z63d~si&@735k!N|E#=tPx<EjD_N$VH_qB#=h(?CF~k1f$9{FcITKv|-M;_t
z+m^n_n3yY9*9P7dZ*On+-J@n##BN}a<!|>_`RSGO89j#|2BevPx7%_;_P~cC``TYy
z@`}qeXV*Qkv$tQLHodR6cV?Zu_7lE@ik+|3^{*9kUVUZz_U&8UPk#DE><;gq=_hK4
z2(2wIDcN$)n(>4z!_L_|TfSDs=5}Olza5=5(ew#l!yVt~LtaZ4m4&@}{W^Q=%|&2U
zn_Jcz8?x<WR`?#Kndt4?<M@u@#9mde8(G516Ra7E%<DO$3zB$1R;1}A?u-fB{dDWC
zBN8Cf&PE=J(K9zQTPAio=U}HH*tE4RGkx4{Pu;M2bFj$$Ca4jfoJSu72M1>@TYTZ_
zRZ+h7n|T5|nH9<xPumcp#oFw+`s%7Jb`};hyp~?D0@>rH`|#4GN#~yj-#&Tjf0fO=
z7(I6$g>r@`c~^waoj>2-)1$FAT4$PrLV%9g&R-x~r8l*lK7IOQMa*sA4a=9OCnYTk
zT3K*+BFObAoT`TMva+GC*;h1v^-;S#Yc&VRsC}w>aeIE8j{o=R<8k@_zpn4s+qvQP
z+j+BQ?J9bDYL@!*qMgR+=kC;gzsqm`r$9yM=a0wz-`BNV%?jmt_x-mlA3O7FkiGf-
z@5=90F0VP7we?>8|G(Ss*X{P|?U%RT7j@@3xbeP1;@iFI_n_wK(=ET>?S8+w-!3bU
zQ(R2UY2k#^Pd7#AtTOl%|K{ym-uA;hYn00wp6m;)vAcif%$cp(*RR;$uY4}M`>vk7
zlIG`Am+#enzpL!tcc<jC@6sSo*~*Vc#jkRleCNGm%a$n~DtqGApG~`LcJbZ2chihi
zCVM_JRVrtAa<9ekyLeoMW8ITyv-9IBKU`TET=e11&CS~UUYqpUx10Jcnz|uw{b}*$
zg9-KZ`=v?)WjS_6`}q2ba<R5u0p;T0caxT!?w7Hv`C<S6XTMdD-gMPm`>HP)ha-Gd
zgeDr>%AGIs{&97EU8r<v;ODqw$B(C{r+Z$SXwC3u>K)a>Y4SUt&#T^|d@?1d&!g*Z
zL7LtC>5sSHDLP%|y&{Z5LQ=BxXwsTjt#=p`&OfbtduuDZT!lkjN>Y-O^^Z&5`X?v4
z%hzss_=Ml?hr`n!(eh4#s(&8x*PmFyUBuq-ck=K4`aj7(Ta%CX{e2z({}P|w?>C!^
zK6I+j%dq(Q>FH@L-unN4zklDH56%kt&DZ0qefQP<e!Knu-}m+Lm484j`p4&OKKmU0
z32M<7+1LNGDRO_uu)uxi|2OIO+1c5}R&)RVIBqXxSM_e^^C#*4&<4E5&ivYK)*z)D
z>Wk`sKAnEm`HJcGZ54mNUVnPIU9M`y!ym2O;!l2jy&k_mzn0tK9m9#*>ibr8e=4>{
z#eQzte!ni-Z^zqhx25{dpE+~l<L-C6xOXa-GhCQ{=kw1$4-dENik*ISQKA>xTCb}t
zEG&FlIRCsl`{IilAX^tG?~LDD^));G_pF+yE0@o^_2Ue<xqirJW5k}1$E5RjJZ$S0
z*H<ck!pC4W>9_U!J&Wgc)P3xZFR7dM_;~+%o6nz~p60jvv0%>6FPHt#pFO+x<1y(;
zr@c?f_aFbh3mRPhb8qH+yYS0oPR+|ps?$$jy>@NcTISEsX6L^v<z(E+e4uW{XOw34
zs`Eljpqx8JU?(#}k^8$7vJ3(0AlEkBVFZb=gNh4H#UgfwCw+G&S~D#0d(wA@kzuDY
z$d#b}H%L>%9mWaPsxI#sKz;loc7`jRAf*cB4j>W6oy=P%-SMAqXS+6hNzMt`oy-UP
zo~)~%U|q!Ckh@{W4vSotC39kQkY}WbouLBFNWo^XkY=E;&QO7-yb|jEiLX}DpT=As
S!OXzGz~JfX=d#Wzp$PygS>fXV

literal 0
HcmV?d00001

-- 
GitLab