ApryseSDK / webviewer-ui

WebViewer UI built in React
Other
415 stars 354 forks source link

Possible unintended re-rendering with importAnnotationsAsync() #53

Closed henry-chris closed 5 years ago

henry-chris commented 5 years ago

V4.0.2.68331 In Chrome

Load annotation file (*.xfdf) with multiple annotations using 'importAnnotationsAsync()' Note this may apply to other functions also. For every annotation imported the OnAnnotationChanged event triggers.

In the NotesPanel, at least for us, this triggers a re-render of every note in the notespanel for each annotation imported. So, if we have 30 annotations in the .XFDF, the NotesPanel re-renders 30 times.

We haven't put a whole lot of thought into the consequences of this, or how this actually affects performance with a lot of annotations for us. However, I would think that the NotesPanel should only re-render a single note at a time when each is imported. It seems that the full list of annotations are sent in the Change event (hence every annotation is re-rendered).

As an addition, when an 'onAnnotationChanged()' event triggers in the notes panel, you grab the unsorted annotations from 'Core' and then sort the entire list for every event. Meaning, not only are you re-rendering 30 times, but you are also re-sorting the exact same list of annotations 30 times the exact same way.

So, this may be intended and we may be over-analyzing the situation, but if not I felt it worth asking the question here. It's difficult to reproduce the exact scenario for each of our problems on your base viewer, so let me know if there's anything else I can supply.

We have debated keeping a stateful list of notes in the NotesPanel and using an 'insert/delete' function for each new mutation to the list after the initial and each subsequent sort. However, like i said we haven't yet come across any significant performance problems related to this as of yet. We will likely test this out with a large annotation set our next sprint.

ZhijieZhang commented 5 years ago

if we have 30 annotations in the .XFDF, the NotesPanel re-renders 30 times.

It's intended that the NotesPanel will be re-rendered every time when there's an annotation changed(added, modified or removed) since we need to update the state in the NotesPanel. One way to improve it is to throttle, is that something you thought of?

However, I would think that the NotesPanel should only re-render a single note at a time when each is imported

We did a test on our end and verified that only the new note is being rendered, and other existing notes are not. Did you see a different behavior?

you grab the unsorted annotations from 'Core' and then sort the entire list for every event

We realized that this is not efficient and one way we can improve it is, like you said, store the sorted notes in the state and when there's an annotation being added/modified we can just do a binary search to get the index for that annotation to insert into. However, when we tested it with large set of annotations, we noticed that sorting annotations too many times isn't the main issue but rather having too many DOM elements upfront. We will work on other improvements first and get back to this if necessary.

For your information, we also noticed that current implementation of NotesPanel is not the best to handle lots and lots of annotations. This is already in our roadmap, and we can let you know when it's merged.

henry-chris commented 5 years ago

It's intended that the NotesPanel will be re-rendered every time when there's an annotation changed(added, modified or removed) since we need to update the state in the NotesPanel. One way to improve it is to throttle, is that something you thought of?

Edit: We aren't throttling the NotesPanel, but we are throttling how often we export/import annotations. We could do that, but I feel like it'd be one of the lesser options.

Well, as I said we haven't actually experienced many problems with the performance yet (which is great). However, we are expecting many XFDFs to contain hundreds of root notes and many more reply/comments. So, the problem here is not that it re-renders everytime an annotation changes, but that 'annotationChanged' seems to be called way more often than needed. Here's one of the main problems (tangentially related to the render) -

  1. We use importAnnotationsAsync() to import manually from a separately stored XFDF. This is not the recommended way, but have been told that it is acceptable.
  2. When you import annots, you seem to automatically send out an onAnnotationChanged event for each found annotation. It seems to not matter if the annotations actually changed or not. For each one imported, the changed event is sent out to several places. In the NotesPanel, this triggers a filter of the annotationList, a sort of the renderlist, and a call to the render() function. This is only in the NotesPanel remember, there are most likely other events triggered that I'm not speaking too.

So if we have 100 annots, we've just called filter/sort/render() 100 times, and each time it has done the exact same thing because the annotationList seems to have had all 100 annots since the first time the event was triggered.

Naively I would say the way to improve this would be to just send the full import list out once and handle a variable amount of changed events in the listeners. But, I have no idea if that's viable.

We did a test on our end and verified that only the new note is being rendered, and other existing notes are not. Did you see a different behavior?

Well, at the time we were having other problems with the panel that resulted in the notes being sorted 2 different ways depending on what initiated it. I'm also not an expert in React yet, so I would definitely say that my concerns were related to the render() function which may not actually cause a DOM change.

We realized that this is not efficient and one way we can improve it is, like you said, store the sorted notes in the state and when there's an annotation being added/modified we can just do a binary search to get the index for that annotation to insert into. However, when we tested it with large set of annotations, we noticed that sorting annotations too many times isn't the main issue but rather having too many DOM elements upfront. We will work on other improvements first and get back to this if necessary.

This would be welcome and ya, I doubt there are any problems with a low to medium amount of annotations. It was more that we were hoping to be proactive once we got some metrics of how many annots/comments we could expect on our side.

For your information, we also noticed that current implementation of NotesPanel is not the best to handle lots and lots of annotations. This is already in our roadmap, and we can let you know when it's merged.

Yup, this would be very welcome, thanks. We have something planned in the next week or two that should give us a current upper limit on our side. If you guys care I can drop some of the findings off here, although it sounds like you already did that.

ZhijieZhang commented 5 years ago

When you call importAnnotationsAsync it will import all annotations in batches and shouldn't be sending out individual annotationChanged events for every single annotation. To confirm, are you seeing 100 annotationChanged events from a single call to importAnnotationsAsync with 100 annotations in the XFDF?

One thing to note is that the async version of importAnnotations will send annotationChanged events out in batches. You can use setAnnotationImportOptions (https://www.pdftron.com/api/web/CoreControls.DocumentViewer.html#setAnnotationImportOptions__anchor) to control the batch size if you feel like too many events are being fired.

You're correct that when calling importAnnotationsAsync an annotation will always be included in the annotationChanged event, regardless of whether the new XFDF caused any properties on the annotation to change. This is only because the implementation is much simpler and generally when calling importAnnotationsAsync you do expect the annotations to be changing.

henry-chris commented 5 years ago

To confirm, are you seeing 100 annotationChanged events from a single call to importAnnotationsAsync with 100 annotations in the XFDF?

Correct. So, it should have triggered annotationChanged 100 times, filtered 100 times, and sorted 100 times, and then called render() 100 times. Is this not what you are seeing? We can give you a more detailed description of our loading and or some code snippets if applicable.

One thing to note is that the async version of importAnnotations will send annotationChanged events out in batches. You can use setAnnotationImportOptions (https://www.pdftron.com/api/web/CoreControls.DocumentViewer.html#setAnnotationImportOptions__anchor) to control the batch size if you feel like too many events are being fired.

Yes, it does specify that the default is 25 (From memory), though, so we didn't really have any reason to change it besides trying to figure out why it was triggering so much. But, since we didn't really know the actual code behind the trigger we figured we'd open this instead as we hadn't experienced much UI slowness yet.

mparizeau-pdftron commented 5 years ago

Sorry for the delay getting back to you. Here's some example code we tried out and we get a single annotationChanged event logged (assuming a document with no internal annotations). The batch size actually changed to 100 in 4.0 (looks the documentation needs to be updated). So this XFDF gets loaded in one batch.

$(document).on('viewerLoaded', function() {
  readerControl.docViewer.getAnnotationManager().on('annotationChanged', function(e, annotations) {
    console.log('change', annotations);
  });
});

$(document).on('documentLoaded', function() {
  var annotManager = readerControl.docViewer.getAnnotationManager();
  annotManager.importAnnotationsAsync(`<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"><pdf-info xmlns="http://www.pdftron.com/pdfinfo" version="2" /><fields /><annots><line page="0" rect="365.387,589.892,559.456,681.592" color="#FF0000" flags="print" name="aee66a46-72d1-46ba-8522-e090dcd6cd3f" title="Matt" subject="Line" date="D:20181107145004-08'00'" creationdate="D:20181107144956-08'00'" start="553.96,675.46" end="370.89,596.02" head="OpenArrow" tail="OpenArrow"><apref gennum="0" objnum="67" x="365.387" y="681.592"/><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104857-08'00'"/></line><square page="0" rect="137.870888,621.900038,274.251281,726.234765" color="#FF00FF" flags="print" name="7d9f5721-7c93-c535-808b-f14aa52840ec" title="Guest" subject="Rectangle" date="D:20181205104900-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104900-08'00'"/><square page="0" rect="270.152416,579.048276,380.076503,674.440026" color="#FF00FF" flags="print" name="5d86e29c-e5a3-60a9-80ca-27220802b640" title="Guest" subject="Rectangle" date="D:20181205104901-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104900-08'00'"/><square page="0" rect="306.669571,609.97607,397.589832,694.561723" color="#FF00FF" flags="print" name="254993b0-9a1e-c37a-8230-f793c74c2f4e" title="Guest" subject="Rectangle" date="D:20181205104901-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104901-08'00'"/><square page="0" rect="381.939623,618.919046,458.700172,704.622571" color="#FF00FF" flags="print" name="a972f3f7-3ae8-6647-1e72-bfde8733f24b" title="Guest" subject="Rectangle" date="D:20181205104902-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104901-08'00'"/><square page="0" rect="425.16401,630.470391,488.882718,719.527532" color="#FF00FF" flags="print" name="0d61ba60-8d71-9208-3a16-dcaaeebc7a58" title="Guest" subject="Rectangle" date="D:20181205104902-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104902-08'00'"/><square page="0" rect="427.772378,641.649112,485.156478,736.295613" color="#FF00FF" flags="print" name="88f2e4f8-e5ac-7d24-1cb4-a2bd0cc80e2c" title="Guest" subject="Rectangle" date="D:20181205104903-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104902-08'00'"/><square page="0" rect="408.395929,654.690952,449.757195,753.808942" color="#FF00FF" flags="print" name="fbf359d1-ad91-2e55-72d1-c1a34c19f13a" title="Guest" subject="Rectangle" date="D:20181205104903-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104903-08'00'"/><square page="0" rect="244.441359,648.728968,366.662038,735.922989" color="#FF00FF" flags="print" name="0ff1c0fb-28c1-9bd1-2faf-d946fc52c892" title="Guest" subject="Rectangle" date="D:20181205104904-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104903-08'00'"/><square page="0" rect="266.053552,651.337336,341.696229,726.607389" color="#FF00FF" flags="print" name="6907da58-6a33-746f-39d0-43c39ba5c63a" title="Guest" subject="Rectangle" date="D:20181205104904-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104904-08'00'"/><square page="0" rect="258.228448,603.641461,409.141177,750.455326" color="#FF00FF" flags="print" name="f4c85328-1e09-d8da-f235-b3dfc028e51f" title="Guest" subject="Rectangle" date="D:20181205104905-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104904-08'00'"/><line page="0" rect="374.89,589.02,560.96,671.46" color="#FF0000" flags="print" name="06fdb682-1776-0b35-e4aa-972089324d8f" title="Guest" subject="Line" date="D:20181205104909-08'00'" creationdate="D:20181205104909-08'00'" start="558.96,670.46" end="375.89,591.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104909-08'00'"/></line><square page="0" rect="142.870888,616.900038,279.251281,721.234765" color="#FF00FF" flags="print" name="5cbea87c-9780-844e-cd65-618a2487c482" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="275.152416,574.048276,385.076503,669.440026" color="#FF00FF" flags="print" name="d6ec5166-55a6-dca7-24d0-5e7dcdc41e5f" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="311.669571,604.97607,402.589832,689.561723" color="#FF00FF" flags="print" name="925c534a-9344-940c-3503-cb6422586a43" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="386.939623,613.919046,463.700172,699.622571" color="#FF00FF" flags="print" name="2572c8a0-a534-d16e-7a03-9d75f6e575c8" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="430.16401,625.470391,493.882718,714.527532" color="#FF00FF" flags="print" name="06fbb66c-a8b8-bcda-9df2-00a1217355d6" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="432.772378,636.649112,490.156478,731.295613" color="#FF00FF" flags="print" name="ab3ab75e-c9eb-24a2-6b9f-85a8e980b5a3" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="413.395929,649.690952,454.757195,748.808942" color="#FF00FF" flags="print" name="efb36457-0f0f-76b6-5296-bf4f4ab30f05" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="249.441359,643.728968,371.662038,730.922989" color="#FF00FF" flags="print" name="120147fc-966a-6528-1517-4b7682d757f5" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="271.053552,646.337336,346.696229,721.607389" color="#FF00FF" flags="print" name="0ce44139-ae81-f909-b01a-1f13c31f3e0f" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="263.228448,598.641461,414.141177,745.455326" color="#FF00FF" flags="print" name="16a55f67-6a6a-dff0-b3c4-1678f57ae978" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><line page="0" rect="384.89,579.02,570.96,661.46" color="#FF0000" flags="print" name="b7aed54e-8f02-87e2-3891-0b9d908d7521" title="Guest" subject="Line" date="D:20181205104909-08'00'" creationdate="D:20181205104909-08'00'" start="568.96,660.46" end="385.89,581.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104909-08'00'"/></line><square page="0" rect="152.870888,606.900038,289.251281,711.234765" color="#FF00FF" flags="print" name="f40e6826-9798-ebb1-89c2-aa92f30e5a0b" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="285.152416,564.048276,395.076503,659.440026" color="#FF00FF" flags="print" name="abee54d1-f087-4529-67eb-3fa34588bb0c" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="321.669571,594.97607,412.589832,679.561723" color="#FF00FF" flags="print" name="33712e5d-130e-d1b7-aafe-1153bb168c70" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="396.939623,603.919046,473.700172,689.622571" color="#FF00FF" flags="print" name="b80fe321-f243-6ced-16c2-9bae6ccfa528" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="440.16401,615.470391,503.882718,704.527532" color="#FF00FF" flags="print" name="daaf0db6-97a1-46ff-2d5d-96776403c586" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="442.772378,626.649112,500.156478,721.295613" color="#FF00FF" flags="print" name="499ef981-47b7-cc78-8849-57d63f3e710e" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="423.395929,639.690952,464.757195,738.808942" color="#FF00FF" flags="print" name="bf1e1eea-2848-e069-d05a-41ec92635ed5" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="259.441359,633.728968,381.662038,720.922989" color="#FF00FF" flags="print" name="f763ab71-59f8-cb37-d617-7485bbd2bf74" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="281.053552,636.337336,356.696229,711.607389" color="#FF00FF" flags="print" name="febf0bc1-adee-b03d-c414-2d42b02ed991" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><square page="0" rect="273.228448,588.641461,424.141177,735.455326" color="#FF00FF" flags="print" name="0ad1bd1f-8683-e8b5-6909-702b5e54bdf9" title="Guest" subject="Rectangle" date="D:20181205104909-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104909-08'00'"/><line page="0" rect="399.89,564.02,585.96,646.46" color="#FF0000" flags="print" name="2735f4ea-1660-e8d2-1e98-672eeec7951f" title="Guest" subject="Line" date="D:20181205104910-08'00'" creationdate="D:20181205104910-08'00'" start="583.96,645.46" end="400.89,566.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104910-08'00'"/></line><square page="0" rect="167.870888,591.900038,304.251281,696.234765" color="#FF00FF" flags="print" name="1359aa89-6220-4575-4d90-22e4ee7d6bda" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="300.152416,549.048276,410.076503,644.440026" color="#FF00FF" flags="print" name="970514da-8d1d-f37f-1bb9-f80761c9b993" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="336.669571,579.97607,427.589832,664.561723" color="#FF00FF" flags="print" name="9c573ebf-dba6-58c2-fc72-29e59bc4676c" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="411.939623,588.919046,488.700172,674.622571" color="#FF00FF" flags="print" name="e6377068-838f-810d-d1eb-85ecb03e1d92" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="455.16401,600.470391,518.882718,689.527532" color="#FF00FF" flags="print" name="fa195d06-eb1c-f851-42ec-b7df603eaddf" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="457.772378,611.649112,515.156478,706.295613" color="#FF00FF" flags="print" name="96971dc3-98e3-10e5-bac5-3fd839528092" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="438.395929,624.690952,479.757195,723.808942" color="#FF00FF" flags="print" name="bf3f385b-97ed-8c6e-74c3-cf6879fb95cb" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="274.441359,618.728968,396.662038,705.922989" color="#FF00FF" flags="print" name="4e411ecf-c636-e664-ee81-a740b7dfa8b4" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="296.053552,621.337336,371.696229,696.607389" color="#FF00FF" flags="print" name="29f1d3a7-a18c-2452-ff0d-b126d24e6179" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="288.228448,573.641461,439.141177,720.455326" color="#FF00FF" flags="print" name="a21b4119-0297-46e6-f5c5-0f70bfbcffbe" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><line page="0" rect="419.89,544.02,605.96,626.46" color="#FF0000" flags="print" name="4c8f8794-69a7-fae0-1470-574083400486" title="Guest" subject="Line" date="D:20181205104910-08'00'" creationdate="D:20181205104910-08'00'" start="603.96,625.46" end="420.89,546.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104910-08'00'"/></line><square page="0" rect="187.870888,571.900038,324.251281,676.234765" color="#FF00FF" flags="print" name="bed655f7-1ff1-cff8-f7fd-e5f56e47f986" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="320.152416,529.048276,430.076503,624.440026" color="#FF00FF" flags="print" name="c5658b05-705a-c424-ff5a-301f3cf1e213" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="356.669571,559.97607,447.589832,644.561723" color="#FF00FF" flags="print" name="ffe74aeb-426e-1e53-0c89-77bdbf0b3495" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="431.939623,568.919046,508.700172,654.622571" color="#FF00FF" flags="print" name="5bc8dfbd-7853-9694-dfae-13de041dcc0a" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="475.16401,580.470391,538.882718,669.527532" color="#FF00FF" flags="print" name="df1b93fb-d46e-00ee-92a6-ca594826ea2e" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="477.772378,591.649112,535.156478,686.295613" color="#FF00FF" flags="print" name="61bf2f6e-7cf6-4208-0bc9-f343d0ec305a" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="458.395929,604.690952,499.757195,703.808942" color="#FF00FF" flags="print" name="cfd2a9de-75e1-6201-9ce4-4ef4bb775e1b" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="294.441359,598.728968,416.662038,685.922989" color="#FF00FF" flags="print" name="c5d11fbb-35b5-f3a6-93de-3931d7df6c72" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="316.053552,601.337336,391.696229,676.607389" color="#FF00FF" flags="print" name="155b77b3-a03c-8808-eb21-2a7a83aead17" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="308.228448,553.641461,459.141177,700.455326" color="#FF00FF" flags="print" name="f74bcd30-7f7c-cc2c-db6f-435513b378ce" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><line page="0" rect="428.32999,519.02,614.39999,601.46" color="#FF0000" flags="print" name="86d231ba-dd3d-132b-b0c5-34356fd12ca0" title="Guest" subject="Line" date="D:20181205104910-08'00'" creationdate="D:20181205104910-08'00'" start="612.4,600.46" end="429.33,521.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104910-08'00'"/></line><square page="0" rect="212.870888,546.900038,349.251281,651.234765" color="#FF00FF" flags="print" name="4cc23afc-d288-60e0-8afd-9e6d4795b390" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="345.152416,504.048276,455.076503,599.440026" color="#FF00FF" flags="print" name="4a14908f-eb1c-5c1e-1f74-a12ec7c3af96" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="381.669571,534.97607,472.589832,619.561723" color="#FF00FF" flags="print" name="5c35eb8f-eff2-91ff-7c05-459c24eb0da8" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="456.939623,543.919046,533.700172,629.622571" color="#FF00FF" flags="print" name="39614b5b-c497-4683-e0f5-2a7d7ba31066" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="500.16401,555.470391,563.882718,644.527532" color="#FF00FF" flags="print" name="1942b54a-1461-bf83-c23e-9730cb992c44" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="502.772378,566.649112,560.156478,661.295613" color="#FF00FF" flags="print" name="863980b9-0332-1c2a-963f-5058741541c8" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="483.395929,579.690952,524.757195,678.808942" color="#FF00FF" flags="print" name="d663778c-c8d2-2a18-f783-2f41b6975f4a" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="319.441359,573.728968,441.662038,660.922989" color="#FF00FF" flags="print" name="4218223f-da99-387a-7af7-75c201949918" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="341.053552,576.337336,416.696229,651.607389" color="#FF00FF" flags="print" name="af8c3f3f-4d3b-6592-79d7-83cfa22db1c3" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><square page="0" rect="333.228448,528.641461,484.141177,675.455326" color="#FF00FF" flags="print" name="60e50f78-35d3-4c69-2608-3f8dbf856b87" title="Guest" subject="Rectangle" date="D:20181205104910-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104910-08'00'"/><line page="0" rect="428.32999,489.02,614.39999,571.46" color="#FF0000" flags="print" name="b83d8e4c-8caa-1fec-e498-b6a973a17e3a" title="Guest" subject="Line" date="D:20181205104911-08'00'" creationdate="D:20181205104911-08'00'" start="612.4,570.46" end="429.33,491.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104911-08'00'"/></line><square page="0" rect="242.870888,516.900038,379.251281,621.234765" color="#FF00FF" flags="print" name="bf7eba4b-7b30-069e-df9c-3151d074fb53" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="375.152416,474.048276,485.076503,569.440026" color="#FF00FF" flags="print" name="b819a224-564a-9fae-c68b-10324b7abe43" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="411.669571,504.97607,502.589832,589.561723" color="#FF00FF" flags="print" name="b006942d-c5c4-9e06-4dfa-22e1188d96b4" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="486.939623,513.919046,563.700172,599.622571" color="#FF00FF" flags="print" name="729bf57e-e4ae-38bc-f593-203a4f23d349" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="530.16401,525.470391,593.882718,614.527532" color="#FF00FF" flags="print" name="fc199bf5-5782-e913-4812-df79a91ccefa" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="532.772378,536.649112,590.156478,631.295613" color="#FF00FF" flags="print" name="5002e7a9-4636-1372-d3c1-4f0378eac60a" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="513.395929,549.690952,554.757195,648.808942" color="#FF00FF" flags="print" name="b471e84c-2e75-71ac-e368-0d5fc441a8fe" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="349.441359,543.728968,471.662038,630.922989" color="#FF00FF" flags="print" name="d55dcfea-b558-5430-4497-33d4ff0da241" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="371.053552,546.337336,446.696229,621.607389" color="#FF00FF" flags="print" name="e1ad1ac8-5710-3e47-77e4-58094da32ccf" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="363.228448,498.641461,514.141177,645.455326" color="#FF00FF" flags="print" name="0959dc9a-9ba1-54de-42c9-6a7efc237f94" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><line page="0" rect="428.32999,454.02,614.39999,536.46" color="#FF0000" flags="print" name="8eba1716-7f72-b041-71d6-d6002e539b6b" title="Guest" subject="Line" date="D:20181205104911-08'00'" creationdate="D:20181205104911-08'00'" start="612.4,535.46" end="429.33,456.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104911-08'00'"/></line><square page="0" rect="277.870888,481.900038,414.251281,586.234765" color="#FF00FF" flags="print" name="600ba5fc-f99b-58b6-3753-8ad85aceea86" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="410.152416,439.048276,520.076503,534.440026" color="#FF00FF" flags="print" name="3db1a089-c489-b52b-6393-7b3c6e3b1967" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="446.669571,469.97607,537.589832,554.561723" color="#FF00FF" flags="print" name="653e5171-1a66-a9da-98ad-9fc6a3cb3b44" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="521.939623,478.919046,598.700172,564.622571" color="#FF00FF" flags="print" name="fb6fd6af-36f7-e20c-ba14-b9d51ecf4623" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="550.681282,490.470391,614.39999,579.527532" color="#FF00FF" flags="print" name="40a46ee2-2422-5129-100e-434aea2b8051" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="557.01589,501.649112,614.39999,596.295613" color="#FF00FF" flags="print" name="05c5702b-be54-2dfa-208c-8168a596736f" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="548.395929,514.690952,589.757195,613.808942" color="#FF00FF" flags="print" name="10cffe28-5683-9af0-fdff-fcd19ce09857" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="384.441359,508.728968,506.662038,595.922989" color="#FF00FF" flags="print" name="00529376-3ed4-677a-fa68-ac9c24a67c28" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="406.053552,511.337336,481.696229,586.607389" color="#FF00FF" flags="print" name="fe70bd5d-1746-6121-dd34-2b8c8cf34fdd" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="398.228448,463.641461,549.141177,610.455326" color="#FF00FF" flags="print" name="73d62fc7-28b3-291b-0ac3-ce89ec6a7875" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><line page="0" rect="428.32999,414.02,614.39999,496.46" color="#FF0000" flags="print" name="c88275de-4e00-c15c-d657-211c04684fdf" title="Guest" subject="Line" date="D:20181205104911-08'00'" creationdate="D:20181205104911-08'00'" start="612.4,495.46" end="429.33,416.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104911-08'00'"/></line><square page="0" rect="317.870888,441.900038,454.251281,546.234765" color="#FF00FF" flags="print" name="b5c49b6f-1e49-fc0f-8804-5282bc8ef910" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="450.152416,399.048276,560.076503,494.440026" color="#FF00FF" flags="print" name="995c85f0-fa2b-d1ef-a3f7-17a967fd7f84" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="486.669571,429.97607,577.589832,514.561723" color="#FF00FF" flags="print" name="f74eb9a7-3afd-b9f2-695e-2670ab52ba97" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="537.639441,438.919046,614.39999,524.622571" color="#FF00FF" flags="print" name="ea6939db-45b0-4010-65bb-ff47c7900b70" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="550.681282,450.470391,614.39999,539.527532" color="#FF00FF" flags="print" name="11f70b2e-20fd-fd2f-0e38-61e3c4b928b8" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="557.01589,461.649112,614.39999,556.295613" color="#FF00FF" flags="print" name="ce0917e0-1986-ff27-f739-98edb61da732" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="573.038724,474.690952,614.39999,573.808942" color="#FF00FF" flags="print" name="80212601-da6c-525e-945d-f191d62e2593" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="424.441359,468.728968,546.662038,555.922989" color="#FF00FF" flags="print" name="8d8de31e-a9a0-3c40-66e3-1d1473fbb22c" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="446.053552,471.337336,521.696229,546.607389" color="#FF00FF" flags="print" name="ffcf98c0-7287-d334-5e88-7a0944053708" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><square page="0" rect="438.228448,423.641461,589.141177,570.455326" color="#FF00FF" flags="print" name="dd1e0d05-d2bd-49ec-98c1-154e9dce71e5" title="Guest" subject="Rectangle" date="D:20181205104911-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104911-08'00'"/><line page="0" rect="428.32999,369.02,614.39999,451.46" color="#FF0000" flags="print" name="646b3ec2-2ac3-30e1-799b-3e4b043eed47" title="Guest" subject="Line" date="D:20181205104912-08'00'" creationdate="D:20181205104912-08'00'" start="612.4,450.46" end="429.33,371.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104912-08'00'"/></line><square page="0" rect="362.870888,396.900038,499.251281,501.234765" color="#FF00FF" flags="print" name="425af322-9db7-6a4c-5931-b888d874563d" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="495.152416,354.048276,605.076503,449.440026" color="#FF00FF" flags="print" name="19a9d06a-4711-434b-7435-989eecdb7ff6" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="523.479729,384.97607,614.39999,469.561723" color="#FF00FF" flags="print" name="ff0f0bfb-9ab2-aa70-be1f-5aae2e55e334" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="537.639441,393.919046,614.39999,479.622571" color="#FF00FF" flags="print" name="696a9cb4-72b0-64ce-5d88-e13f7f479a43" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="550.681282,405.470391,614.39999,494.527532" color="#FF00FF" flags="print" name="0390bcf3-f0b6-3881-669f-b7d2958f1506" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="557.01589,416.649112,614.39999,511.295613" color="#FF00FF" flags="print" name="ed72fd88-8ded-02c9-bc86-e3ad91305117" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="573.038724,429.690952,614.39999,528.808942" color="#FF00FF" flags="print" name="849d22b4-7a1d-9854-af92-7b3227c86a32" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="469.441359,423.728968,591.662038,510.922989" color="#FF00FF" flags="print" name="fcf08866-533e-5b3e-3fb1-a33de138f2e2" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="491.053552,426.337336,566.696229,501.607389" color="#FF00FF" flags="print" name="46a9ef1c-cdcb-2842-b63f-0ba1a547ebf7" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="463.487261,378.641461,614.39999,525.455326" color="#FF00FF" flags="print" name="1f55a1bb-1b07-afb2-a80f-9c27b968b964" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><line page="0" rect="428.32999,319.02,614.39999,401.46" color="#FF0000" flags="print" name="05782fa7-c045-752b-4528-84e9d0bd8906" title="Guest" subject="Line" date="D:20181205104912-08'00'" creationdate="D:20181205104912-08'00'" start="612.4,400.46" end="429.33,321.02" head="OpenArrow" tail="OpenArrow"><popup page="0" rect="614.4,515.742,794.4,635.742" flags="print,nozoom,norotate" date="D:20181205104912-08'00'"/></line><square page="0" rect="412.870888,346.900038,549.251281,451.234765" color="#FF00FF" flags="print" name="a1cf78c6-32aa-74cf-e036-9695982f028b" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="504.475903,304.048276,614.39999,399.440026" color="#FF00FF" flags="print" name="9e8ba0f3-6e39-5464-7064-25210bbf75fd" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="523.479729,334.97607,614.39999,419.561723" color="#FF00FF" flags="print" name="238c3167-2333-6a66-ff7d-221545854b30" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="537.639441,343.919046,614.39999,429.622571" color="#FF00FF" flags="print" name="f25f14f3-8c14-a5cd-2dae-83e3e43289c1" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="550.681282,355.470391,614.39999,444.527532" color="#FF00FF" flags="print" name="4c194370-926d-d430-3ad3-21ed6dc6b880" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="557.01589,366.649112,614.39999,461.295613" color="#FF00FF" flags="print" name="81c78e2a-2acb-3b0f-f9d4-46f94d2162f8" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="573.038724,379.690952,614.39999,478.808942" color="#FF00FF" flags="print" name="7fc43aa3-5c97-154b-3850-88161a842c8f" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="492.179311,373.728968,614.39999,460.922989" color="#FF00FF" flags="print" name="1bb1a81d-4221-e701-de99-71e93dacc500" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="538.757313,376.337336,614.39999,451.607389" color="#FF00FF" flags="print" name="7c7aedc6-e440-8717-dee7-5e25cc2a2206" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/><square page="0" rect="463.487261,328.641461,614.39999,475.455326" color="#FF00FF" flags="print" name="fd194b8c-326d-8a98-65ff-f1f69d5ff963" title="Guest" subject="Rectangle" date="D:20181205104912-08'00'" interior-color="#00FFFF" width="3" creationdate="D:20181205104912-08'00'"/></annots><pages><defmtx matrix="1,0,0,-1,0,779.52" /><pgmtx matrix="1,0,0,-1,0,783.3599999999999" page="1" /><pgmtx matrix="1,0,0,-1,0,794.88" page="2" /><pgmtx matrix="1,0,0,-1,0,783.3599999999999" page="4" /><pgmtx matrix="1,0,0,-1,0,783.3599999999999" page="5" /><pgmtx matrix="1,0,0,-1,0,791.03999" page="6" /><pgmtx matrix="1,0,0,-1,0,794.88" page="7" /><pgmtx matrix="1,0,0,-1,0,783.3599999999999" page="8" /><pgmtx matrix="1,0,0,-1,0,783.3599999999999" page="9" /><pgmtx matrix="1,0,0,-1,0,787.2" page="10" /><pgmtx matrix="1,0,0,-1,0,791.03999" page="11" /></pages></xfdf>`);
});
henry-chris commented 5 years ago

I will test that XFDF and get back to you.

EDIT: We do use a callback function. In your documentation : https://www.pdftron.com/api/web/CoreControls.AnnotationManager.html#importAnnotationsAsync__anchor

You do not list the callback as optional, and the callback would seem to be the reason to use the 'async' function over the regular importAnnotations() function.

I'm going to take the callback out of our code and see if I see the same results as you.

henry-chris commented 5 years ago

Alright, tested it out. Here's a picture:

image

I set the XFDF for this file to be the xfdf you gave me above. It obviously renders off the page, but still seems to work.

Here is the changeset for the initial importAnnotationsAsync(). I've removed the callback function from our code so it's exactly like yours.

image

The above seems to sync with your assertion, though I am seeing 3 annotchanged events and not 1. I think the PDF might have one baked in or something.

Then, if you look in the top right of the annotations, you see a little green squiggly. I made a single freehand annotation there (by accident at first). Here is the changelog from that:

image image image image

What's happening here is that it's set up to save out that added annotation to the XFDF on the server then grab the new XFDF and import the annotations again except with the new one added. This allows for continual testing of the XFDF you gave me, and everytime I do this it triggers annotChanged N times. Where N is the current number of annotations. Each changed event sends a single annotation, looping through each one imported or in the list...unsure.

So maybe that's our problem, we don't have full control over the XFDFs yet so we have to poll for changes and that means we mostly don't import command XMLs but full XFDFs every so often. If you re-import the same XFDF does it replace each annotation and trigger a new event for each one?

If so that's a problem we are causing. I can write something that filters that out until we get more control over the file storage. You've already suggested that unchanged, imported annotations are meant to trigger a new event.

So, I guess we are good with this behavior unless you guys have something to add. Sorry to waste your time on this one.

mparizeau-pdftron commented 5 years ago

Ahh I see, yes when re-importing the same XFDF I do see the individual change events. Taking a quick look it does look like we could consolidate the change events without too much work. We'll add it to the backlog to take a closer look and possibly add the change to the next release.