@contractkit/plugin-bruno 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">87.27% </span>
26
+ <span class="strong">88.26% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>288/330</span>
28
+ <span class='fraction'>331/375</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">76.29% </span>
33
+ <span class="strong">78.1% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>206/270</span>
35
+ <span class='fraction'>239/306</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">92.15% </span>
40
+ <span class="strong">93.22% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>47/51</span>
42
+ <span class='fraction'>55/59</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">88.54% </span>
47
+ <span class="strong">89.29% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>255/288</span>
49
+ <span class='fraction'>292/327</span>
50
50
  </div>
51
51
 
52
52
 
@@ -762,7 +762,216 @@
762
762
  <a name='L697'></a><a href='#L697'>697</a>
763
763
  <a name='L698'></a><a href='#L698'>698</a>
764
764
  <a name='L699'></a><a href='#L699'>699</a>
765
- <a name='L700'></a><a href='#L700'>700</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
765
+ <a name='L700'></a><a href='#L700'>700</a>
766
+ <a name='L701'></a><a href='#L701'>701</a>
767
+ <a name='L702'></a><a href='#L702'>702</a>
768
+ <a name='L703'></a><a href='#L703'>703</a>
769
+ <a name='L704'></a><a href='#L704'>704</a>
770
+ <a name='L705'></a><a href='#L705'>705</a>
771
+ <a name='L706'></a><a href='#L706'>706</a>
772
+ <a name='L707'></a><a href='#L707'>707</a>
773
+ <a name='L708'></a><a href='#L708'>708</a>
774
+ <a name='L709'></a><a href='#L709'>709</a>
775
+ <a name='L710'></a><a href='#L710'>710</a>
776
+ <a name='L711'></a><a href='#L711'>711</a>
777
+ <a name='L712'></a><a href='#L712'>712</a>
778
+ <a name='L713'></a><a href='#L713'>713</a>
779
+ <a name='L714'></a><a href='#L714'>714</a>
780
+ <a name='L715'></a><a href='#L715'>715</a>
781
+ <a name='L716'></a><a href='#L716'>716</a>
782
+ <a name='L717'></a><a href='#L717'>717</a>
783
+ <a name='L718'></a><a href='#L718'>718</a>
784
+ <a name='L719'></a><a href='#L719'>719</a>
785
+ <a name='L720'></a><a href='#L720'>720</a>
786
+ <a name='L721'></a><a href='#L721'>721</a>
787
+ <a name='L722'></a><a href='#L722'>722</a>
788
+ <a name='L723'></a><a href='#L723'>723</a>
789
+ <a name='L724'></a><a href='#L724'>724</a>
790
+ <a name='L725'></a><a href='#L725'>725</a>
791
+ <a name='L726'></a><a href='#L726'>726</a>
792
+ <a name='L727'></a><a href='#L727'>727</a>
793
+ <a name='L728'></a><a href='#L728'>728</a>
794
+ <a name='L729'></a><a href='#L729'>729</a>
795
+ <a name='L730'></a><a href='#L730'>730</a>
796
+ <a name='L731'></a><a href='#L731'>731</a>
797
+ <a name='L732'></a><a href='#L732'>732</a>
798
+ <a name='L733'></a><a href='#L733'>733</a>
799
+ <a name='L734'></a><a href='#L734'>734</a>
800
+ <a name='L735'></a><a href='#L735'>735</a>
801
+ <a name='L736'></a><a href='#L736'>736</a>
802
+ <a name='L737'></a><a href='#L737'>737</a>
803
+ <a name='L738'></a><a href='#L738'>738</a>
804
+ <a name='L739'></a><a href='#L739'>739</a>
805
+ <a name='L740'></a><a href='#L740'>740</a>
806
+ <a name='L741'></a><a href='#L741'>741</a>
807
+ <a name='L742'></a><a href='#L742'>742</a>
808
+ <a name='L743'></a><a href='#L743'>743</a>
809
+ <a name='L744'></a><a href='#L744'>744</a>
810
+ <a name='L745'></a><a href='#L745'>745</a>
811
+ <a name='L746'></a><a href='#L746'>746</a>
812
+ <a name='L747'></a><a href='#L747'>747</a>
813
+ <a name='L748'></a><a href='#L748'>748</a>
814
+ <a name='L749'></a><a href='#L749'>749</a>
815
+ <a name='L750'></a><a href='#L750'>750</a>
816
+ <a name='L751'></a><a href='#L751'>751</a>
817
+ <a name='L752'></a><a href='#L752'>752</a>
818
+ <a name='L753'></a><a href='#L753'>753</a>
819
+ <a name='L754'></a><a href='#L754'>754</a>
820
+ <a name='L755'></a><a href='#L755'>755</a>
821
+ <a name='L756'></a><a href='#L756'>756</a>
822
+ <a name='L757'></a><a href='#L757'>757</a>
823
+ <a name='L758'></a><a href='#L758'>758</a>
824
+ <a name='L759'></a><a href='#L759'>759</a>
825
+ <a name='L760'></a><a href='#L760'>760</a>
826
+ <a name='L761'></a><a href='#L761'>761</a>
827
+ <a name='L762'></a><a href='#L762'>762</a>
828
+ <a name='L763'></a><a href='#L763'>763</a>
829
+ <a name='L764'></a><a href='#L764'>764</a>
830
+ <a name='L765'></a><a href='#L765'>765</a>
831
+ <a name='L766'></a><a href='#L766'>766</a>
832
+ <a name='L767'></a><a href='#L767'>767</a>
833
+ <a name='L768'></a><a href='#L768'>768</a>
834
+ <a name='L769'></a><a href='#L769'>769</a>
835
+ <a name='L770'></a><a href='#L770'>770</a>
836
+ <a name='L771'></a><a href='#L771'>771</a>
837
+ <a name='L772'></a><a href='#L772'>772</a>
838
+ <a name='L773'></a><a href='#L773'>773</a>
839
+ <a name='L774'></a><a href='#L774'>774</a>
840
+ <a name='L775'></a><a href='#L775'>775</a>
841
+ <a name='L776'></a><a href='#L776'>776</a>
842
+ <a name='L777'></a><a href='#L777'>777</a>
843
+ <a name='L778'></a><a href='#L778'>778</a>
844
+ <a name='L779'></a><a href='#L779'>779</a>
845
+ <a name='L780'></a><a href='#L780'>780</a>
846
+ <a name='L781'></a><a href='#L781'>781</a>
847
+ <a name='L782'></a><a href='#L782'>782</a>
848
+ <a name='L783'></a><a href='#L783'>783</a>
849
+ <a name='L784'></a><a href='#L784'>784</a>
850
+ <a name='L785'></a><a href='#L785'>785</a>
851
+ <a name='L786'></a><a href='#L786'>786</a>
852
+ <a name='L787'></a><a href='#L787'>787</a>
853
+ <a name='L788'></a><a href='#L788'>788</a>
854
+ <a name='L789'></a><a href='#L789'>789</a>
855
+ <a name='L790'></a><a href='#L790'>790</a>
856
+ <a name='L791'></a><a href='#L791'>791</a>
857
+ <a name='L792'></a><a href='#L792'>792</a>
858
+ <a name='L793'></a><a href='#L793'>793</a>
859
+ <a name='L794'></a><a href='#L794'>794</a>
860
+ <a name='L795'></a><a href='#L795'>795</a>
861
+ <a name='L796'></a><a href='#L796'>796</a>
862
+ <a name='L797'></a><a href='#L797'>797</a>
863
+ <a name='L798'></a><a href='#L798'>798</a>
864
+ <a name='L799'></a><a href='#L799'>799</a>
865
+ <a name='L800'></a><a href='#L800'>800</a>
866
+ <a name='L801'></a><a href='#L801'>801</a>
867
+ <a name='L802'></a><a href='#L802'>802</a>
868
+ <a name='L803'></a><a href='#L803'>803</a>
869
+ <a name='L804'></a><a href='#L804'>804</a>
870
+ <a name='L805'></a><a href='#L805'>805</a>
871
+ <a name='L806'></a><a href='#L806'>806</a>
872
+ <a name='L807'></a><a href='#L807'>807</a>
873
+ <a name='L808'></a><a href='#L808'>808</a>
874
+ <a name='L809'></a><a href='#L809'>809</a>
875
+ <a name='L810'></a><a href='#L810'>810</a>
876
+ <a name='L811'></a><a href='#L811'>811</a>
877
+ <a name='L812'></a><a href='#L812'>812</a>
878
+ <a name='L813'></a><a href='#L813'>813</a>
879
+ <a name='L814'></a><a href='#L814'>814</a>
880
+ <a name='L815'></a><a href='#L815'>815</a>
881
+ <a name='L816'></a><a href='#L816'>816</a>
882
+ <a name='L817'></a><a href='#L817'>817</a>
883
+ <a name='L818'></a><a href='#L818'>818</a>
884
+ <a name='L819'></a><a href='#L819'>819</a>
885
+ <a name='L820'></a><a href='#L820'>820</a>
886
+ <a name='L821'></a><a href='#L821'>821</a>
887
+ <a name='L822'></a><a href='#L822'>822</a>
888
+ <a name='L823'></a><a href='#L823'>823</a>
889
+ <a name='L824'></a><a href='#L824'>824</a>
890
+ <a name='L825'></a><a href='#L825'>825</a>
891
+ <a name='L826'></a><a href='#L826'>826</a>
892
+ <a name='L827'></a><a href='#L827'>827</a>
893
+ <a name='L828'></a><a href='#L828'>828</a>
894
+ <a name='L829'></a><a href='#L829'>829</a>
895
+ <a name='L830'></a><a href='#L830'>830</a>
896
+ <a name='L831'></a><a href='#L831'>831</a>
897
+ <a name='L832'></a><a href='#L832'>832</a>
898
+ <a name='L833'></a><a href='#L833'>833</a>
899
+ <a name='L834'></a><a href='#L834'>834</a>
900
+ <a name='L835'></a><a href='#L835'>835</a>
901
+ <a name='L836'></a><a href='#L836'>836</a>
902
+ <a name='L837'></a><a href='#L837'>837</a>
903
+ <a name='L838'></a><a href='#L838'>838</a>
904
+ <a name='L839'></a><a href='#L839'>839</a>
905
+ <a name='L840'></a><a href='#L840'>840</a>
906
+ <a name='L841'></a><a href='#L841'>841</a>
907
+ <a name='L842'></a><a href='#L842'>842</a>
908
+ <a name='L843'></a><a href='#L843'>843</a>
909
+ <a name='L844'></a><a href='#L844'>844</a>
910
+ <a name='L845'></a><a href='#L845'>845</a>
911
+ <a name='L846'></a><a href='#L846'>846</a>
912
+ <a name='L847'></a><a href='#L847'>847</a>
913
+ <a name='L848'></a><a href='#L848'>848</a>
914
+ <a name='L849'></a><a href='#L849'>849</a>
915
+ <a name='L850'></a><a href='#L850'>850</a>
916
+ <a name='L851'></a><a href='#L851'>851</a>
917
+ <a name='L852'></a><a href='#L852'>852</a>
918
+ <a name='L853'></a><a href='#L853'>853</a>
919
+ <a name='L854'></a><a href='#L854'>854</a>
920
+ <a name='L855'></a><a href='#L855'>855</a>
921
+ <a name='L856'></a><a href='#L856'>856</a>
922
+ <a name='L857'></a><a href='#L857'>857</a>
923
+ <a name='L858'></a><a href='#L858'>858</a>
924
+ <a name='L859'></a><a href='#L859'>859</a>
925
+ <a name='L860'></a><a href='#L860'>860</a>
926
+ <a name='L861'></a><a href='#L861'>861</a>
927
+ <a name='L862'></a><a href='#L862'>862</a>
928
+ <a name='L863'></a><a href='#L863'>863</a>
929
+ <a name='L864'></a><a href='#L864'>864</a>
930
+ <a name='L865'></a><a href='#L865'>865</a>
931
+ <a name='L866'></a><a href='#L866'>866</a>
932
+ <a name='L867'></a><a href='#L867'>867</a>
933
+ <a name='L868'></a><a href='#L868'>868</a>
934
+ <a name='L869'></a><a href='#L869'>869</a>
935
+ <a name='L870'></a><a href='#L870'>870</a>
936
+ <a name='L871'></a><a href='#L871'>871</a>
937
+ <a name='L872'></a><a href='#L872'>872</a>
938
+ <a name='L873'></a><a href='#L873'>873</a>
939
+ <a name='L874'></a><a href='#L874'>874</a>
940
+ <a name='L875'></a><a href='#L875'>875</a>
941
+ <a name='L876'></a><a href='#L876'>876</a>
942
+ <a name='L877'></a><a href='#L877'>877</a>
943
+ <a name='L878'></a><a href='#L878'>878</a>
944
+ <a name='L879'></a><a href='#L879'>879</a>
945
+ <a name='L880'></a><a href='#L880'>880</a>
946
+ <a name='L881'></a><a href='#L881'>881</a>
947
+ <a name='L882'></a><a href='#L882'>882</a>
948
+ <a name='L883'></a><a href='#L883'>883</a>
949
+ <a name='L884'></a><a href='#L884'>884</a>
950
+ <a name='L885'></a><a href='#L885'>885</a>
951
+ <a name='L886'></a><a href='#L886'>886</a>
952
+ <a name='L887'></a><a href='#L887'>887</a>
953
+ <a name='L888'></a><a href='#L888'>888</a>
954
+ <a name='L889'></a><a href='#L889'>889</a>
955
+ <a name='L890'></a><a href='#L890'>890</a>
956
+ <a name='L891'></a><a href='#L891'>891</a>
957
+ <a name='L892'></a><a href='#L892'>892</a>
958
+ <a name='L893'></a><a href='#L893'>893</a>
959
+ <a name='L894'></a><a href='#L894'>894</a>
960
+ <a name='L895'></a><a href='#L895'>895</a>
961
+ <a name='L896'></a><a href='#L896'>896</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
962
+ <span class="cline-any cline-neutral">&nbsp;</span>
963
+ <span class="cline-any cline-neutral">&nbsp;</span>
964
+ <span class="cline-any cline-neutral">&nbsp;</span>
965
+ <span class="cline-any cline-neutral">&nbsp;</span>
966
+ <span class="cline-any cline-neutral">&nbsp;</span>
967
+ <span class="cline-any cline-neutral">&nbsp;</span>
968
+ <span class="cline-any cline-neutral">&nbsp;</span>
969
+ <span class="cline-any cline-neutral">&nbsp;</span>
970
+ <span class="cline-any cline-neutral">&nbsp;</span>
971
+ <span class="cline-any cline-neutral">&nbsp;</span>
972
+ <span class="cline-any cline-neutral">&nbsp;</span>
973
+ <span class="cline-any cline-neutral">&nbsp;</span>
974
+ <span class="cline-any cline-neutral">&nbsp;</span>
766
975
  <span class="cline-any cline-neutral">&nbsp;</span>
767
976
  <span class="cline-any cline-neutral">&nbsp;</span>
768
977
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -791,6 +1000,40 @@
791
1000
  <span class="cline-any cline-neutral">&nbsp;</span>
792
1001
  <span class="cline-any cline-neutral">&nbsp;</span>
793
1002
  <span class="cline-any cline-neutral">&nbsp;</span>
1003
+ <span class="cline-any cline-yes">1x</span>
1004
+ <span class="cline-any cline-neutral">&nbsp;</span>
1005
+ <span class="cline-any cline-neutral">&nbsp;</span>
1006
+ <span class="cline-any cline-neutral">&nbsp;</span>
1007
+ <span class="cline-any cline-neutral">&nbsp;</span>
1008
+ <span class="cline-any cline-neutral">&nbsp;</span>
1009
+ <span class="cline-any cline-neutral">&nbsp;</span>
1010
+ <span class="cline-any cline-neutral">&nbsp;</span>
1011
+ <span class="cline-any cline-neutral">&nbsp;</span>
1012
+ <span class="cline-any cline-neutral">&nbsp;</span>
1013
+ <span class="cline-any cline-neutral">&nbsp;</span>
1014
+ <span class="cline-any cline-neutral">&nbsp;</span>
1015
+ <span class="cline-any cline-neutral">&nbsp;</span>
1016
+ <span class="cline-any cline-neutral">&nbsp;</span>
1017
+ <span class="cline-any cline-neutral">&nbsp;</span>
1018
+ <span class="cline-any cline-neutral">&nbsp;</span>
1019
+ <span class="cline-any cline-neutral">&nbsp;</span>
1020
+ <span class="cline-any cline-neutral">&nbsp;</span>
1021
+ <span class="cline-any cline-neutral">&nbsp;</span>
1022
+ <span class="cline-any cline-neutral">&nbsp;</span>
1023
+ <span class="cline-any cline-neutral">&nbsp;</span>
1024
+ <span class="cline-any cline-neutral">&nbsp;</span>
1025
+ <span class="cline-any cline-neutral">&nbsp;</span>
1026
+ <span class="cline-any cline-neutral">&nbsp;</span>
1027
+ <span class="cline-any cline-neutral">&nbsp;</span>
1028
+ <span class="cline-any cline-neutral">&nbsp;</span>
1029
+ <span class="cline-any cline-neutral">&nbsp;</span>
1030
+ <span class="cline-any cline-neutral">&nbsp;</span>
1031
+ <span class="cline-any cline-neutral">&nbsp;</span>
1032
+ <span class="cline-any cline-neutral">&nbsp;</span>
1033
+ <span class="cline-any cline-neutral">&nbsp;</span>
1034
+ <span class="cline-any cline-neutral">&nbsp;</span>
1035
+ <span class="cline-any cline-neutral">&nbsp;</span>
1036
+ <span class="cline-any cline-neutral">&nbsp;</span>
794
1037
  <span class="cline-any cline-neutral">&nbsp;</span>
795
1038
  <span class="cline-any cline-neutral">&nbsp;</span>
796
1039
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -838,23 +1081,44 @@
838
1081
  <span class="cline-any cline-neutral">&nbsp;</span>
839
1082
  <span class="cline-any cline-neutral">&nbsp;</span>
840
1083
  <span class="cline-any cline-neutral">&nbsp;</span>
841
- <span class="cline-any cline-yes">93x</span>
842
1084
  <span class="cline-any cline-neutral">&nbsp;</span>
843
- <span class="cline-any cline-yes">93x</span>
844
- <span class="cline-any cline-yes">93x</span>
845
- <span class="cline-any cline-yes">93x</span>
846
- <span class="cline-any cline-yes">93x</span>
847
- <span class="cline-any cline-yes">93x</span>
848
1085
  <span class="cline-any cline-neutral">&nbsp;</span>
849
- <span class="cline-any cline-yes">93x</span>
850
- <span class="cline-any cline-yes">93x</span>
851
1086
  <span class="cline-any cline-yes">94x</span>
1087
+ <span class="cline-any cline-yes">94x</span>
1088
+ <span class="cline-any cline-neutral">&nbsp;</span>
1089
+ <span class="cline-any cline-neutral">&nbsp;</span>
1090
+ <span class="cline-any cline-neutral">&nbsp;</span>
1091
+ <span class="cline-any cline-neutral">&nbsp;</span>
1092
+ <span class="cline-any cline-neutral">&nbsp;</span>
1093
+ <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-neutral">&nbsp;</span>
1095
+ <span class="cline-any cline-neutral">&nbsp;</span>
1096
+ <span class="cline-any cline-neutral">&nbsp;</span>
1097
+ <span class="cline-any cline-neutral">&nbsp;</span>
1098
+ <span class="cline-any cline-neutral">&nbsp;</span>
1099
+ <span class="cline-any cline-neutral">&nbsp;</span>
1100
+ <span class="cline-any cline-neutral">&nbsp;</span>
1101
+ <span class="cline-any cline-neutral">&nbsp;</span>
1102
+ <span class="cline-any cline-neutral">&nbsp;</span>
1103
+ <span class="cline-any cline-yes">4x</span>
1104
+ <span class="cline-any cline-neutral">&nbsp;</span>
1105
+ <span class="cline-any cline-yes">106x</span>
1106
+ <span class="cline-any cline-yes">106x</span>
1107
+ <span class="cline-any cline-yes">106x</span>
1108
+ <span class="cline-any cline-yes">106x</span>
1109
+ <span class="cline-any cline-yes">106x</span>
852
1110
  <span class="cline-any cline-neutral">&nbsp;</span>
853
1111
  <span class="cline-any cline-neutral">&nbsp;</span>
1112
+ <span class="cline-any cline-yes">106x</span>
1113
+ <span class="cline-any cline-yes">106x</span>
854
1114
  <span class="cline-any cline-neutral">&nbsp;</span>
855
1115
  <span class="cline-any cline-neutral">&nbsp;</span>
856
1116
  <span class="cline-any cline-neutral">&nbsp;</span>
857
- <span class="cline-any cline-yes">93x</span>
1117
+ <span class="cline-any cline-yes">106x</span>
1118
+ <span class="cline-any cline-yes">107x</span>
1119
+ <span class="cline-any cline-neutral">&nbsp;</span>
1120
+ <span class="cline-any cline-neutral">&nbsp;</span>
1121
+ <span class="cline-any cline-yes">106x</span>
858
1122
  <span class="cline-any cline-yes">4x</span>
859
1123
  <span class="cline-any cline-yes">4x</span>
860
1124
  <span class="cline-any cline-yes">4x</span>
@@ -862,65 +1126,193 @@
862
1126
  <span class="cline-any cline-no">&nbsp;</span>
863
1127
  <span class="cline-any cline-neutral">&nbsp;</span>
864
1128
  <span class="cline-any cline-neutral">&nbsp;</span>
865
- <span class="cline-any cline-yes">93x</span>
866
- <span class="cline-any cline-yes">95x</span>
867
- <span class="cline-any cline-yes">95x</span>
868
- <span class="cline-any cline-yes">95x</span>
869
- <span class="cline-any cline-neutral">&nbsp;</span>
870
- <span class="cline-any cline-yes">95x</span>
1129
+ <span class="cline-any cline-yes">106x</span>
1130
+ <span class="cline-any cline-yes">106x</span>
1131
+ <span class="cline-any cline-yes">108x</span>
1132
+ <span class="cline-any cline-yes">108x</span>
1133
+ <span class="cline-any cline-yes">108x</span>
1134
+ <span class="cline-any cline-yes">108x</span>
871
1135
  <span class="cline-any cline-neutral">&nbsp;</span>
872
- <span class="cline-any cline-yes">95x</span>
873
- <span class="cline-any cline-yes">95x</span>
874
- <span class="cline-any cline-yes">95x</span>
1136
+ <span class="cline-any cline-yes">108x</span>
1137
+ <span class="cline-any cline-yes">108x</span>
1138
+ <span class="cline-any cline-yes">108x</span>
875
1139
  <span class="cline-any cline-neutral">&nbsp;</span>
876
- <span class="cline-any cline-yes">95x</span>
1140
+ <span class="cline-any cline-yes">108x</span>
877
1141
  <span class="cline-any cline-yes">4x</span>
878
1142
  <span class="cline-any cline-yes">4x</span>
879
1143
  <span class="cline-any cline-neutral">&nbsp;</span>
880
1144
  <span class="cline-any cline-neutral">&nbsp;</span>
1145
+ <span class="cline-any cline-yes">108x</span>
1146
+ <span class="cline-any cline-yes">124x</span>
1147
+ <span class="cline-any cline-neutral">&nbsp;</span>
1148
+ <span class="cline-any cline-neutral">&nbsp;</span>
1149
+ <span class="cline-any cline-yes">119x</span>
1150
+ <span class="cline-any cline-neutral">&nbsp;</span>
1151
+ <span class="cline-any cline-neutral">&nbsp;</span>
1152
+ <span class="cline-any cline-neutral">&nbsp;</span>
1153
+ <span class="cline-any cline-neutral">&nbsp;</span>
1154
+ <span class="cline-any cline-yes">108x</span>
1155
+ <span class="cline-any cline-neutral">&nbsp;</span>
1156
+ <span class="cline-any cline-neutral">&nbsp;</span>
1157
+ <span class="cline-any cline-neutral">&nbsp;</span>
1158
+ <span class="cline-any cline-neutral">&nbsp;</span>
1159
+ <span class="cline-any cline-neutral">&nbsp;</span>
1160
+ <span class="cline-any cline-neutral">&nbsp;</span>
1161
+ <span class="cline-any cline-neutral">&nbsp;</span>
1162
+ <span class="cline-any cline-neutral">&nbsp;</span>
1163
+ <span class="cline-any cline-yes">108x</span>
1164
+ <span class="cline-any cline-neutral">&nbsp;</span>
1165
+ <span class="cline-any cline-neutral">&nbsp;</span>
1166
+ <span class="cline-any cline-neutral">&nbsp;</span>
1167
+ <span class="cline-any cline-neutral">&nbsp;</span>
1168
+ <span class="cline-any cline-neutral">&nbsp;</span>
1169
+ <span class="cline-any cline-neutral">&nbsp;</span>
1170
+ <span class="cline-any cline-neutral">&nbsp;</span>
1171
+ <span class="cline-any cline-neutral">&nbsp;</span>
1172
+ <span class="cline-any cline-neutral">&nbsp;</span>
1173
+ <span class="cline-any cline-yes">108x</span>
1174
+ <span class="cline-any cline-yes">108x</span>
1175
+ <span class="cline-any cline-yes">111x</span>
1176
+ <span class="cline-any cline-yes">125x</span>
1177
+ <span class="cline-any cline-yes">124x</span>
1178
+ <span class="cline-any cline-neutral">&nbsp;</span>
1179
+ <span class="cline-any cline-neutral">&nbsp;</span>
1180
+ <span class="cline-any cline-yes">108x</span>
1181
+ <span class="cline-any cline-neutral">&nbsp;</span>
1182
+ <span class="cline-any cline-yes">108x</span>
1183
+ <span class="cline-any cline-yes">108x</span>
1184
+ <span class="cline-any cline-yes">108x</span>
1185
+ <span class="cline-any cline-yes">124x</span>
1186
+ <span class="cline-any cline-yes">124x</span>
1187
+ <span class="cline-any cline-neutral">&nbsp;</span>
1188
+ <span class="cline-any cline-neutral">&nbsp;</span>
1189
+ <span class="cline-any cline-neutral">&nbsp;</span>
1190
+ <span class="cline-any cline-neutral">&nbsp;</span>
881
1191
  <span class="cline-any cline-neutral">&nbsp;</span>
882
- <span class="cline-any cline-yes">95x</span>
883
- <span class="cline-any cline-yes">95x</span>
884
- <span class="cline-any cline-yes">98x</span>
885
- <span class="cline-any cline-yes">102x</span>
886
- <span class="cline-any cline-yes">101x</span>
887
1192
  <span class="cline-any cline-neutral">&nbsp;</span>
888
1193
  <span class="cline-any cline-neutral">&nbsp;</span>
889
- <span class="cline-any cline-yes">95x</span>
890
1194
  <span class="cline-any cline-neutral">&nbsp;</span>
891
- <span class="cline-any cline-yes">95x</span>
892
- <span class="cline-any cline-yes">95x</span>
893
- <span class="cline-any cline-yes">101x</span>
894
- <span class="cline-any cline-yes">101x</span>
895
- <span class="cline-any cline-yes">101x</span>
896
- <span class="cline-any cline-yes">101x</span>
1195
+ <span class="cline-any cline-yes">124x</span>
1196
+ <span class="cline-any cline-neutral">&nbsp;</span>
1197
+ <span class="cline-any cline-yes">108x</span>
1198
+ <span class="cline-any cline-neutral">&nbsp;</span>
1199
+ <span class="cline-any cline-neutral">&nbsp;</span>
1200
+ <span class="cline-any cline-neutral">&nbsp;</span>
1201
+ <span class="cline-any cline-neutral">&nbsp;</span>
1202
+ <span class="cline-any cline-neutral">&nbsp;</span>
1203
+ <span class="cline-any cline-neutral">&nbsp;</span>
1204
+ <span class="cline-any cline-neutral">&nbsp;</span>
1205
+ <span class="cline-any cline-neutral">&nbsp;</span>
1206
+ <span class="cline-any cline-neutral">&nbsp;</span>
1207
+ <span class="cline-any cline-yes">119x</span>
1208
+ <span class="cline-any cline-yes">119x</span>
1209
+ <span class="cline-any cline-yes">119x</span>
1210
+ <span class="cline-any cline-yes">119x</span>
897
1211
  <span class="cline-any cline-yes">5x</span>
898
1212
  <span class="cline-any cline-neutral">&nbsp;</span>
899
- <span class="cline-any cline-yes">101x</span>
900
- <span class="cline-any cline-yes">101x</span>
1213
+ <span class="cline-any cline-yes">119x</span>
1214
+ <span class="cline-any cline-neutral">&nbsp;</span>
1215
+ <span class="cline-any cline-neutral">&nbsp;</span>
1216
+ <span class="cline-any cline-neutral">&nbsp;</span>
1217
+ <span class="cline-any cline-neutral">&nbsp;</span>
1218
+ <span class="cline-any cline-neutral">&nbsp;</span>
1219
+ <span class="cline-any cline-neutral">&nbsp;</span>
1220
+ <span class="cline-any cline-neutral">&nbsp;</span>
1221
+ <span class="cline-any cline-neutral">&nbsp;</span>
1222
+ <span class="cline-any cline-neutral">&nbsp;</span>
1223
+ <span class="cline-any cline-yes">124x</span>
1224
+ <span class="cline-any cline-yes">124x</span>
1225
+ <span class="cline-any cline-yes">124x</span>
1226
+ <span class="cline-any cline-yes">20x</span>
1227
+ <span class="cline-any cline-yes">20x</span>
1228
+ <span class="cline-any cline-neutral">&nbsp;</span>
1229
+ <span class="cline-any cline-neutral">&nbsp;</span>
1230
+ <span class="cline-any cline-neutral">&nbsp;</span>
1231
+ <span class="cline-any cline-yes">124x</span>
1232
+ <span class="cline-any cline-neutral">&nbsp;</span>
1233
+ <span class="cline-any cline-neutral">&nbsp;</span>
1234
+ <span class="cline-any cline-neutral">&nbsp;</span>
1235
+ <span class="cline-any cline-neutral">&nbsp;</span>
1236
+ <span class="cline-any cline-neutral">&nbsp;</span>
1237
+ <span class="cline-any cline-neutral">&nbsp;</span>
1238
+ <span class="cline-any cline-yes">124x</span>
1239
+ <span class="cline-any cline-neutral">&nbsp;</span>
1240
+ <span class="cline-any cline-neutral">&nbsp;</span>
901
1241
  <span class="cline-any cline-neutral">&nbsp;</span>
902
1242
  <span class="cline-any cline-neutral">&nbsp;</span>
903
1243
  <span class="cline-any cline-neutral">&nbsp;</span>
904
- <span class="cline-any cline-yes">387x</span>
905
- <span class="cline-any cline-yes">95x</span>
906
1244
  <span class="cline-any cline-neutral">&nbsp;</span>
907
1245
  <span class="cline-any cline-neutral">&nbsp;</span>
908
1246
  <span class="cline-any cline-neutral">&nbsp;</span>
909
1247
  <span class="cline-any cline-neutral">&nbsp;</span>
910
- <span class="cline-any cline-yes">95x</span>
911
1248
  <span class="cline-any cline-neutral">&nbsp;</span>
912
1249
  <span class="cline-any cline-neutral">&nbsp;</span>
913
1250
  <span class="cline-any cline-neutral">&nbsp;</span>
914
1251
  <span class="cline-any cline-neutral">&nbsp;</span>
1252
+ <span class="cline-any cline-neutral">&nbsp;</span>
1253
+ <span class="cline-any cline-neutral">&nbsp;</span>
1254
+ <span class="cline-any cline-neutral">&nbsp;</span>
1255
+ <span class="cline-any cline-neutral">&nbsp;</span>
1256
+ <span class="cline-any cline-yes">124x</span>
1257
+ <span class="cline-any cline-yes">124x</span>
1258
+ <span class="cline-any cline-yes">124x</span>
1259
+ <span class="cline-any cline-yes">124x</span>
1260
+ <span class="cline-any cline-yes">124x</span>
1261
+ <span class="cline-any cline-yes">23x</span>
1262
+ <span class="cline-any cline-neutral">&nbsp;</span>
1263
+ <span class="cline-any cline-yes">124x</span>
1264
+ <span class="cline-any cline-yes">11x</span>
1265
+ <span class="cline-any cline-yes">11x</span>
1266
+ <span class="cline-any cline-yes">2x</span>
1267
+ <span class="cline-any cline-neutral">&nbsp;</span>
1268
+ <span class="cline-any cline-neutral">&nbsp;</span>
1269
+ <span class="cline-any cline-yes">124x</span>
1270
+ <span class="cline-any cline-neutral">&nbsp;</span>
1271
+ <span class="cline-any cline-neutral">&nbsp;</span>
1272
+ <span class="cline-any cline-neutral">&nbsp;</span>
1273
+ <span class="cline-any cline-yes">372x</span>
1274
+ <span class="cline-any cline-yes">18x</span>
1275
+ <span class="cline-any cline-yes">19x</span>
915
1276
  <span class="cline-any cline-yes">5x</span>
916
1277
  <span class="cline-any cline-yes">5x</span>
1278
+ <span class="cline-any cline-no">&nbsp;</span>
1279
+ <span class="cline-any cline-no">&nbsp;</span>
1280
+ <span class="cline-any cline-neutral">&nbsp;</span>
1281
+ <span class="cline-any cline-neutral">&nbsp;</span>
1282
+ <span class="cline-any cline-neutral">&nbsp;</span>
1283
+ <span class="cline-any cline-neutral">&nbsp;</span>
1284
+ <span class="cline-any cline-neutral">&nbsp;</span>
1285
+ <span class="cline-any cline-yes">105x</span>
1286
+ <span class="cline-any cline-neutral">&nbsp;</span>
1287
+ <span class="cline-any cline-neutral">&nbsp;</span>
1288
+ <span class="cline-any cline-neutral">&nbsp;</span>
1289
+ <span class="cline-any cline-neutral">&nbsp;</span>
1290
+ <span class="cline-any cline-neutral">&nbsp;</span>
1291
+ <span class="cline-any cline-neutral">&nbsp;</span>
1292
+ <span class="cline-any cline-neutral">&nbsp;</span>
1293
+ <span class="cline-any cline-neutral">&nbsp;</span>
1294
+ <span class="cline-any cline-neutral">&nbsp;</span>
1295
+ <span class="cline-any cline-neutral">&nbsp;</span>
1296
+ <span class="cline-any cline-neutral">&nbsp;</span>
1297
+ <span class="cline-any cline-neutral">&nbsp;</span>
1298
+ <span class="cline-any cline-yes">8x</span>
1299
+ <span class="cline-any cline-neutral">&nbsp;</span>
1300
+ <span class="cline-any cline-neutral">&nbsp;</span>
1301
+ <span class="cline-any cline-yes">8x</span>
917
1302
  <span class="cline-any cline-yes">7x</span>
918
- <span class="cline-any cline-yes">1x</span>
1303
+ <span class="cline-any cline-yes">7x</span>
1304
+ <span class="cline-any cline-yes">7x</span>
1305
+ <span class="cline-any cline-yes">2x</span>
919
1306
  <span class="cline-any cline-neutral">&nbsp;</span>
920
1307
  <span class="cline-any cline-neutral">&nbsp;</span>
921
1308
  <span class="cline-any cline-neutral">&nbsp;</span>
922
1309
  <span class="cline-any cline-neutral">&nbsp;</span>
923
- <span class="cline-any cline-yes">4x</span>
1310
+ <span class="cline-any cline-neutral">&nbsp;</span>
1311
+ <span class="cline-any cline-neutral">&nbsp;</span>
1312
+ <span class="cline-any cline-neutral">&nbsp;</span>
1313
+ <span class="cline-any cline-neutral">&nbsp;</span>
1314
+ <span class="cline-any cline-neutral">&nbsp;</span>
1315
+ <span class="cline-any cline-yes">5x</span>
924
1316
  <span class="cline-any cline-neutral">&nbsp;</span>
925
1317
  <span class="cline-any cline-neutral">&nbsp;</span>
926
1318
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -966,42 +1358,42 @@
966
1358
  <span class="cline-any cline-neutral">&nbsp;</span>
967
1359
  <span class="cline-any cline-neutral">&nbsp;</span>
968
1360
  <span class="cline-any cline-neutral">&nbsp;</span>
969
- <span class="cline-any cline-yes">93x</span>
970
- <span class="cline-any cline-yes">93x</span>
1361
+ <span class="cline-any cline-yes">106x</span>
1362
+ <span class="cline-any cline-yes">106x</span>
971
1363
  <span class="cline-any cline-yes">7x</span>
972
1364
  <span class="cline-any cline-yes">7x</span>
973
1365
  <span class="cline-any cline-yes">7x</span>
974
1366
  <span class="cline-any cline-neutral">&nbsp;</span>
975
- <span class="cline-any cline-yes">93x</span>
976
- <span class="cline-any cline-yes">93x</span>
1367
+ <span class="cline-any cline-yes">106x</span>
1368
+ <span class="cline-any cline-yes">106x</span>
977
1369
  <span class="cline-any cline-neutral">&nbsp;</span>
978
1370
  <span class="cline-any cline-neutral">&nbsp;</span>
979
1371
  <span class="cline-any cline-neutral">&nbsp;</span>
980
1372
  <span class="cline-any cline-neutral">&nbsp;</span>
981
1373
  <span class="cline-any cline-neutral">&nbsp;</span>
982
1374
  <span class="cline-any cline-neutral">&nbsp;</span>
983
- <span class="cline-any cline-yes">93x</span>
1375
+ <span class="cline-any cline-yes">106x</span>
984
1376
  <span class="cline-any cline-yes">4x</span>
985
1377
  <span class="cline-any cline-neutral">&nbsp;</span>
986
1378
  <span class="cline-any cline-neutral">&nbsp;</span>
987
1379
  <span class="cline-any cline-neutral">&nbsp;</span>
988
1380
  <span class="cline-any cline-neutral">&nbsp;</span>
989
- <span class="cline-any cline-yes">90x</span>
990
- <span class="cline-any cline-yes">90x</span>
1381
+ <span class="cline-any cline-yes">103x</span>
1382
+ <span class="cline-any cline-yes">103x</span>
991
1383
  <span class="cline-any cline-yes">7x</span>
992
1384
  <span class="cline-any cline-neutral">&nbsp;</span>
993
- <span class="cline-any cline-yes">90x</span>
1385
+ <span class="cline-any cline-yes">103x</span>
994
1386
  <span class="cline-any cline-neutral">&nbsp;</span>
995
1387
  <span class="cline-any cline-neutral">&nbsp;</span>
996
1388
  <span class="cline-any cline-neutral">&nbsp;</span>
997
- <span class="cline-any cline-yes">94x</span>
998
- <span class="cline-any cline-yes">94x</span>
999
- <span class="cline-any cline-yes">104x</span>
1000
- <span class="cline-any cline-yes">104x</span>
1001
- <span class="cline-any cline-yes">104x</span>
1389
+ <span class="cline-any cline-yes">107x</span>
1390
+ <span class="cline-any cline-yes">107x</span>
1391
+ <span class="cline-any cline-yes">117x</span>
1392
+ <span class="cline-any cline-yes">117x</span>
1393
+ <span class="cline-any cline-yes">117x</span>
1002
1394
  <span class="cline-any cline-neutral">&nbsp;</span>
1003
- <span class="cline-any cline-yes">94x</span>
1004
- <span class="cline-any cline-yes">94x</span>
1395
+ <span class="cline-any cline-yes">107x</span>
1396
+ <span class="cline-any cline-yes">107x</span>
1005
1397
  <span class="cline-any cline-neutral">&nbsp;</span>
1006
1398
  <span class="cline-any cline-neutral">&nbsp;</span>
1007
1399
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1009,7 +1401,7 @@
1009
1401
  <span class="cline-any cline-neutral">&nbsp;</span>
1010
1402
  <span class="cline-any cline-neutral">&nbsp;</span>
1011
1403
  <span class="cline-any cline-neutral">&nbsp;</span>
1012
- <span class="cline-any cline-yes">99x</span>
1404
+ <span class="cline-any cline-yes">112x</span>
1013
1405
  <span class="cline-any cline-neutral">&nbsp;</span>
1014
1406
  <span class="cline-any cline-neutral">&nbsp;</span>
1015
1407
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1022,31 +1414,31 @@
1022
1414
  <span class="cline-any cline-neutral">&nbsp;</span>
1023
1415
  <span class="cline-any cline-neutral">&nbsp;</span>
1024
1416
  <span class="cline-any cline-neutral">&nbsp;</span>
1025
- <span class="cline-any cline-yes">101x</span>
1417
+ <span class="cline-any cline-yes">119x</span>
1026
1418
  <span class="cline-any cline-neutral">&nbsp;</span>
1027
- <span class="cline-any cline-yes">101x</span>
1028
- <span class="cline-any cline-yes">101x</span>
1029
- <span class="cline-any cline-yes">101x</span>
1030
- <span class="cline-any cline-yes">101x</span>
1031
- <span class="cline-any cline-yes">101x</span>
1032
- <span class="cline-any cline-yes">101x</span>
1033
- <span class="cline-any cline-yes">101x</span>
1034
- <span class="cline-any cline-yes">101x</span>
1419
+ <span class="cline-any cline-yes">119x</span>
1420
+ <span class="cline-any cline-yes">119x</span>
1421
+ <span class="cline-any cline-yes">119x</span>
1422
+ <span class="cline-any cline-yes">119x</span>
1423
+ <span class="cline-any cline-yes">119x</span>
1424
+ <span class="cline-any cline-yes">119x</span>
1425
+ <span class="cline-any cline-yes">119x</span>
1426
+ <span class="cline-any cline-yes">119x</span>
1035
1427
  <span class="cline-any cline-neutral">&nbsp;</span>
1036
1428
  <span class="cline-any cline-neutral">&nbsp;</span>
1037
1429
  <span class="cline-any cline-neutral">&nbsp;</span>
1038
- <span class="cline-any cline-yes">101x</span>
1430
+ <span class="cline-any cline-yes">119x</span>
1039
1431
  <span class="cline-any cline-neutral">&nbsp;</span>
1040
1432
  <span class="cline-any cline-neutral">&nbsp;</span>
1041
1433
  <span class="cline-any cline-neutral">&nbsp;</span>
1042
1434
  <span class="cline-any cline-neutral">&nbsp;</span>
1043
1435
  <span class="cline-any cline-neutral">&nbsp;</span>
1044
- <span class="cline-any cline-yes">101x</span>
1436
+ <span class="cline-any cline-yes">119x</span>
1045
1437
  <span class="cline-any cline-yes">15x</span>
1046
1438
  <span class="cline-any cline-neutral">&nbsp;</span>
1047
- <span class="cline-any cline-yes">101x</span>
1439
+ <span class="cline-any cline-yes">119x</span>
1048
1440
  <span class="cline-any cline-neutral">&nbsp;</span>
1049
- <span class="cline-any cline-yes">101x</span>
1441
+ <span class="cline-any cline-yes">119x</span>
1050
1442
  <span class="cline-any cline-yes">20x</span>
1051
1443
  <span class="cline-any cline-yes">20x</span>
1052
1444
  <span class="cline-any cline-yes">29x</span>
@@ -1057,7 +1449,7 @@
1057
1449
  <span class="cline-any cline-neutral">&nbsp;</span>
1058
1450
  <span class="cline-any cline-neutral">&nbsp;</span>
1059
1451
  <span class="cline-any cline-neutral">&nbsp;</span>
1060
- <span class="cline-any cline-yes">101x</span>
1452
+ <span class="cline-any cline-yes">119x</span>
1061
1453
  <span class="cline-any cline-yes">4x</span>
1062
1454
  <span class="cline-any cline-yes">4x</span>
1063
1455
  <span class="cline-any cline-yes">4x</span>
@@ -1070,7 +1462,7 @@
1070
1462
  <span class="cline-any cline-neutral">&nbsp;</span>
1071
1463
  <span class="cline-any cline-neutral">&nbsp;</span>
1072
1464
  <span class="cline-any cline-neutral">&nbsp;</span>
1073
- <span class="cline-any cline-yes">101x</span>
1465
+ <span class="cline-any cline-yes">119x</span>
1074
1466
  <span class="cline-any cline-yes">7x</span>
1075
1467
  <span class="cline-any cline-yes">7x</span>
1076
1468
  <span class="cline-any cline-yes">1x</span>
@@ -1081,37 +1473,37 @@
1081
1473
  <span class="cline-any cline-neutral">&nbsp;</span>
1082
1474
  <span class="cline-any cline-neutral">&nbsp;</span>
1083
1475
  <span class="cline-any cline-neutral">&nbsp;</span>
1084
- <span class="cline-any cline-yes">101x</span>
1085
- <span class="cline-any cline-yes">19x</span>
1476
+ <span class="cline-any cline-yes">119x</span>
1477
+ <span class="cline-any cline-yes">23x</span>
1086
1478
  <span class="cline-any cline-neutral">&nbsp;</span>
1087
1479
  <span class="cline-any cline-neutral">&nbsp;</span>
1088
1480
  <span class="cline-any cline-neutral">&nbsp;</span>
1089
1481
  <span class="cline-any cline-neutral">&nbsp;</span>
1090
1482
  <span class="cline-any cline-neutral">&nbsp;</span>
1091
- <span class="cline-any cline-yes">57x</span>
1483
+ <span class="cline-any cline-yes">69x</span>
1092
1484
  <span class="cline-any cline-neutral">&nbsp;</span>
1093
- <span class="cline-any cline-yes">19x</span>
1094
- <span class="cline-any cline-yes">19x</span>
1485
+ <span class="cline-any cline-yes">23x</span>
1486
+ <span class="cline-any cline-yes">23x</span>
1095
1487
  <span class="cline-any cline-yes">1x</span>
1096
1488
  <span class="cline-any cline-yes">1x</span>
1097
- <span class="cline-any cline-yes">18x</span>
1489
+ <span class="cline-any cline-yes">22x</span>
1098
1490
  <span class="cline-any cline-no">&nbsp;</span>
1099
1491
  <span class="cline-any cline-no">&nbsp;</span>
1100
1492
  <span class="cline-any cline-neutral">&nbsp;</span>
1101
- <span class="cline-any cline-yes">18x</span>
1102
- <span class="cline-any cline-yes">18x</span>
1103
- <span class="cline-any cline-yes">18x</span>
1104
- <span class="cline-any cline-yes">18x</span>
1105
- <span class="cline-any cline-yes">60x</span>
1493
+ <span class="cline-any cline-yes">22x</span>
1494
+ <span class="cline-any cline-yes">22x</span>
1495
+ <span class="cline-any cline-yes">22x</span>
1496
+ <span class="cline-any cline-yes">22x</span>
1497
+ <span class="cline-any cline-yes">69x</span>
1106
1498
  <span class="cline-any cline-neutral">&nbsp;</span>
1107
1499
  <span class="cline-any cline-neutral">&nbsp;</span>
1108
1500
  <span class="cline-any cline-neutral">&nbsp;</span>
1109
1501
  <span class="cline-any cline-neutral">&nbsp;</span>
1110
1502
  <span class="cline-any cline-neutral">&nbsp;</span>
1111
- <span class="cline-any cline-yes">101x</span>
1112
- <span class="cline-any cline-yes">101x</span>
1113
- <span class="cline-any cline-yes">101x</span>
1114
- <span class="cline-any cline-yes">101x</span>
1503
+ <span class="cline-any cline-yes">119x</span>
1504
+ <span class="cline-any cline-yes">119x</span>
1505
+ <span class="cline-any cline-yes">119x</span>
1506
+ <span class="cline-any cline-yes">119x</span>
1115
1507
  <span class="cline-any cline-yes">10x</span>
1116
1508
  <span class="cline-any cline-yes">10x</span>
1117
1509
  <span class="cline-any cline-yes">10x</span>
@@ -1128,8 +1520,8 @@
1128
1520
  <span class="cline-any cline-neutral">&nbsp;</span>
1129
1521
  <span class="cline-any cline-neutral">&nbsp;</span>
1130
1522
  <span class="cline-any cline-neutral">&nbsp;</span>
1131
- <span class="cline-any cline-yes">101x</span>
1132
- <span class="cline-any cline-yes">101x</span>
1523
+ <span class="cline-any cline-yes">119x</span>
1524
+ <span class="cline-any cline-yes">119x</span>
1133
1525
  <span class="cline-any cline-yes">3x</span>
1134
1526
  <span class="cline-any cline-yes">3x</span>
1135
1527
  <span class="cline-any cline-yes">3x</span>
@@ -1137,23 +1529,23 @@
1137
1529
  <span class="cline-any cline-neutral">&nbsp;</span>
1138
1530
  <span class="cline-any cline-neutral">&nbsp;</span>
1139
1531
  <span class="cline-any cline-neutral">&nbsp;</span>
1140
- <span class="cline-any cline-yes">101x</span>
1141
- <span class="cline-any cline-yes">101x</span>
1532
+ <span class="cline-any cline-yes">119x</span>
1533
+ <span class="cline-any cline-yes">119x</span>
1142
1534
  <span class="cline-any cline-neutral">&nbsp;</span>
1143
1535
  <span class="cline-any cline-neutral">&nbsp;</span>
1144
1536
  <span class="cline-any cline-neutral">&nbsp;</span>
1145
1537
  <span class="cline-any cline-neutral">&nbsp;</span>
1146
- <span class="cline-any cline-yes">101x</span>
1147
- <span class="cline-any cline-yes">101x</span>
1538
+ <span class="cline-any cline-yes">119x</span>
1539
+ <span class="cline-any cline-yes">119x</span>
1148
1540
  <span class="cline-any cline-neutral">&nbsp;</span>
1149
1541
  <span class="cline-any cline-neutral">&nbsp;</span>
1150
1542
  <span class="cline-any cline-neutral">&nbsp;</span>
1151
1543
  <span class="cline-any cline-neutral">&nbsp;</span>
1152
- <span class="cline-any cline-yes">101x</span>
1153
- <span class="cline-any cline-yes">101x</span>
1154
- <span class="cline-any cline-yes">101x</span>
1155
- <span class="cline-any cline-yes">101x</span>
1156
- <span class="cline-any cline-yes">101x</span>
1544
+ <span class="cline-any cline-yes">119x</span>
1545
+ <span class="cline-any cline-yes">119x</span>
1546
+ <span class="cline-any cline-yes">119x</span>
1547
+ <span class="cline-any cline-yes">119x</span>
1548
+ <span class="cline-any cline-yes">119x</span>
1157
1549
  <span class="cline-any cline-yes">1x</span>
1158
1550
  <span class="cline-any cline-yes">1x</span>
1159
1551
  <span class="cline-any cline-yes">2x</span>
@@ -1162,7 +1554,7 @@
1162
1554
  <span class="cline-any cline-neutral">&nbsp;</span>
1163
1555
  <span class="cline-any cline-yes">1x</span>
1164
1556
  <span class="cline-any cline-neutral">&nbsp;</span>
1165
- <span class="cline-any cline-yes">101x</span>
1557
+ <span class="cline-any cline-yes">119x</span>
1166
1558
  <span class="cline-any cline-neutral">&nbsp;</span>
1167
1559
  <span class="cline-any cline-neutral">&nbsp;</span>
1168
1560
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1194,25 +1586,25 @@
1194
1586
  <span class="cline-any cline-neutral">&nbsp;</span>
1195
1587
  <span class="cline-any cline-neutral">&nbsp;</span>
1196
1588
  <span class="cline-any cline-neutral">&nbsp;</span>
1197
- <span class="cline-any cline-yes">93x</span>
1198
- <span class="cline-any cline-yes">93x</span>
1199
- <span class="cline-any cline-yes">8x</span>
1200
- <span class="cline-any cline-yes">9x</span>
1589
+ <span class="cline-any cline-yes">106x</span>
1590
+ <span class="cline-any cline-yes">106x</span>
1591
+ <span class="cline-any cline-yes">10x</span>
1592
+ <span class="cline-any cline-yes">11x</span>
1201
1593
  <span class="cline-any cline-neutral">&nbsp;</span>
1202
1594
  <span class="cline-any cline-neutral">&nbsp;</span>
1203
- <span class="cline-any cline-yes">93x</span>
1595
+ <span class="cline-any cline-yes">106x</span>
1204
1596
  <span class="cline-any cline-neutral">&nbsp;</span>
1205
1597
  <span class="cline-any cline-neutral">&nbsp;</span>
1206
1598
  <span class="cline-any cline-neutral">&nbsp;</span>
1207
1599
  <span class="cline-any cline-neutral">&nbsp;</span>
1208
- <span class="cline-any cline-yes">9x</span>
1209
- <span class="cline-any cline-yes">9x</span>
1600
+ <span class="cline-any cline-yes">11x</span>
1601
+ <span class="cline-any cline-yes">11x</span>
1210
1602
  <span class="cline-any cline-yes">1x</span>
1211
1603
  <span class="cline-any cline-yes">1x</span>
1212
1604
  <span class="cline-any cline-yes">1x</span>
1213
1605
  <span class="cline-any cline-neutral">&nbsp;</span>
1214
1606
  <span class="cline-any cline-neutral">&nbsp;</span>
1215
- <span class="cline-any cline-yes">9x</span>
1607
+ <span class="cline-any cline-yes">11x</span>
1216
1608
  <span class="cline-any cline-neutral">&nbsp;</span>
1217
1609
  <span class="cline-any cline-neutral">&nbsp;</span>
1218
1610
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1332,11 +1724,11 @@
1332
1724
  <span class="cline-any cline-neutral">&nbsp;</span>
1333
1725
  <span class="cline-any cline-neutral">&nbsp;</span>
1334
1726
  <span class="cline-any cline-neutral">&nbsp;</span>
1335
- <span class="cline-any cline-yes">38x</span>
1727
+ <span class="cline-any cline-yes">45x</span>
1336
1728
  <span class="cline-any cline-neutral">&nbsp;</span>
1337
- <span class="cline-any cline-yes">17x</span>
1729
+ <span class="cline-any cline-yes">22x</span>
1338
1730
  <span class="cline-any cline-neutral">&nbsp;</span>
1339
- <span class="cline-any cline-yes">7x</span>
1731
+ <span class="cline-any cline-yes">11x</span>
1340
1732
  <span class="cline-any cline-neutral">&nbsp;</span>
1341
1733
  <span class="cline-any cline-yes">3x</span>
1342
1734
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1346,7 +1738,7 @@
1346
1738
  <span class="cline-any cline-neutral">&nbsp;</span>
1347
1739
  <span class="cline-any cline-neutral">&nbsp;</span>
1348
1740
  <span class="cline-any cline-neutral">&nbsp;</span>
1349
- <span class="cline-any cline-yes">2x</span>
1741
+ <span class="cline-any cline-yes">3x</span>
1350
1742
  <span class="cline-any cline-neutral">&nbsp;</span>
1351
1743
  <span class="cline-any cline-yes">1x</span>
1352
1744
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1379,11 +1771,11 @@
1379
1771
  <span class="cline-any cline-neutral">&nbsp;</span>
1380
1772
  <span class="cline-any cline-no">&nbsp;</span>
1381
1773
  <span class="cline-any cline-neutral">&nbsp;</span>
1382
- <span class="cline-any cline-yes">9x</span>
1383
- <span class="cline-any cline-yes">9x</span>
1774
+ <span class="cline-any cline-yes">11x</span>
1775
+ <span class="cline-any cline-yes">11x</span>
1384
1776
  <span class="cline-any cline-neutral">&nbsp;</span>
1385
- <span class="cline-any cline-yes">5x</span>
1386
- <span class="cline-any cline-yes">5x</span>
1777
+ <span class="cline-any cline-yes">7x</span>
1778
+ <span class="cline-any cline-yes">7x</span>
1387
1779
  <span class="cline-any cline-neutral">&nbsp;</span>
1388
1780
  <span class="cline-any cline-neutral">&nbsp;</span>
1389
1781
  <span class="cline-any cline-no">&nbsp;</span>
@@ -1396,28 +1788,28 @@
1396
1788
  <span class="cline-any cline-neutral">&nbsp;</span>
1397
1789
  <span class="cline-any cline-neutral">&nbsp;</span>
1398
1790
  <span class="cline-any cline-neutral">&nbsp;</span>
1399
- <span class="cline-any cline-yes">5x</span>
1791
+ <span class="cline-any cline-yes">7x</span>
1400
1792
  <span class="cline-any cline-neutral">&nbsp;</span>
1401
1793
  <span class="cline-any cline-neutral">&nbsp;</span>
1402
1794
  <span class="cline-any cline-neutral">&nbsp;</span>
1403
1795
  <span class="cline-any cline-neutral">&nbsp;</span>
1404
- <span class="cline-any cline-yes">15x</span>
1405
- <span class="cline-any cline-yes">15x</span>
1796
+ <span class="cline-any cline-yes">17x</span>
1797
+ <span class="cline-any cline-yes">17x</span>
1798
+ <span class="cline-any cline-yes">32x</span>
1406
1799
  <span class="cline-any cline-yes">29x</span>
1407
- <span class="cline-any cline-yes">26x</span>
1408
1800
  <span class="cline-any cline-yes">6x</span>
1409
- <span class="cline-any cline-yes">20x</span>
1410
- <span class="cline-any cline-yes">19x</span>
1801
+ <span class="cline-any cline-yes">23x</span>
1802
+ <span class="cline-any cline-yes">22x</span>
1411
1803
  <span class="cline-any cline-neutral">&nbsp;</span>
1412
1804
  <span class="cline-any cline-neutral">&nbsp;</span>
1413
- <span class="cline-any cline-yes">15x</span>
1805
+ <span class="cline-any cline-yes">17x</span>
1414
1806
  <span class="cline-any cline-neutral">&nbsp;</span>
1415
1807
  <span class="cline-any cline-neutral">&nbsp;</span>
1416
1808
  <span class="cline-any cline-neutral">&nbsp;</span>
1417
1809
  <span class="cline-any cline-neutral">&nbsp;</span>
1418
1810
  <span class="cline-any cline-neutral">&nbsp;</span>
1419
1811
  <span class="cline-any cline-neutral">&nbsp;</span>
1420
- <span class="cline-any cline-yes">101x</span>
1812
+ <span class="cline-any cline-yes">119x</span>
1421
1813
  <span class="cline-any cline-neutral">&nbsp;</span>
1422
1814
  <span class="cline-any cline-neutral">&nbsp;</span>
1423
1815
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1431,24 +1823,24 @@
1431
1823
  <span class="cline-any cline-neutral">&nbsp;</span>
1432
1824
  <span class="cline-any cline-neutral">&nbsp;</span>
1433
1825
  <span class="cline-any cline-neutral">&nbsp;</span>
1434
- <span class="cline-any cline-yes">101x</span>
1826
+ <span class="cline-any cline-yes">124x</span>
1435
1827
  <span class="cline-any cline-neutral">&nbsp;</span>
1436
1828
  <span class="cline-any cline-neutral">&nbsp;</span>
1437
1829
  <span class="cline-any cline-neutral">&nbsp;</span>
1438
1830
  <span class="cline-any cline-neutral">&nbsp;</span>
1439
1831
  <span class="cline-any cline-neutral">&nbsp;</span>
1440
1832
  <span class="cline-any cline-neutral">&nbsp;</span>
1441
- <span class="cline-any cline-yes">101x</span>
1833
+ <span class="cline-any cline-yes">124x</span>
1442
1834
  <span class="cline-any cline-neutral">&nbsp;</span>
1443
1835
  <span class="cline-any cline-neutral">&nbsp;</span>
1444
1836
  <span class="cline-any cline-neutral">&nbsp;</span>
1445
1837
  <span class="cline-any cline-neutral">&nbsp;</span>
1446
- <span class="cline-any cline-yes">101x</span>
1838
+ <span class="cline-any cline-yes">119x</span>
1447
1839
  <span class="cline-any cline-neutral">&nbsp;</span>
1448
1840
  <span class="cline-any cline-neutral">&nbsp;</span>
1449
1841
  <span class="cline-any cline-neutral">&nbsp;</span>
1450
1842
  <span class="cline-any cline-neutral">&nbsp;</span>
1451
- <span class="cline-any cline-yes">92x</span>
1843
+ <span class="cline-any cline-yes">105x</span>
1452
1844
  <span class="cline-any cline-neutral">&nbsp;</span>
1453
1845
  <span class="cline-any cline-neutral">&nbsp;</span>
1454
1846
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1456,10 +1848,10 @@
1456
1848
  <span class="cline-any cline-neutral">&nbsp;</span>
1457
1849
  <span class="cline-any cline-neutral">&nbsp;</span>
1458
1850
  <span class="cline-any cline-neutral">&nbsp;</span>
1459
- <span class="cline-any cline-yes">394x</span>
1460
- <span class="cline-any cline-yes">115x</span>
1851
+ <span class="cline-any cline-yes">456x</span>
1852
+ <span class="cline-any cline-yes">133x</span>
1461
1853
  <span class="cline-any cline-neutral">&nbsp;</span>
1462
- <span class="cline-any cline-yes">279x</span>
1854
+ <span class="cline-any cline-yes">323x</span>
1463
1855
  <span class="cline-any cline-neutral">&nbsp;</span>
1464
1856
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type {
1465
1857
  OpRootNode,
@@ -1471,8 +1863,21 @@
1471
1863
  ContractRootNode,
1472
1864
  ModelNode,
1473
1865
  FieldNode,
1866
+ IncrementalManifest,
1867
+ IncrementalUnit,
1868
+ IncrementalResult as IncrementalResultBase,
1869
+ } from '@contractkit/core';
1870
+ import {
1871
+ resolveSecurity,
1872
+ resolveModifiers,
1873
+ SECURITY_NONE,
1874
+ collectTransitiveModelRefs,
1875
+ runIncrementalCodegen,
1876
+ parseIncrementalManifest,
1877
+ emptyIncrementalManifest,
1878
+ hashFingerprint,
1879
+ INCREMENTAL_MANIFEST_VERSION,
1474
1880
  } from '@contractkit/core';
1475
- import { resolveSecurity, resolveModifiers, SECURITY_NONE } from '@contractkit/core';
1476
1881
  import { basename } from 'path';
1477
1882
  import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
1478
1883
  &nbsp;
@@ -1485,6 +1890,13 @@ export interface OpenCollectionFile {
1485
1890
  /** Manifest filename — tracks which files this plugin previously generated so subsequent runs can clean up only those, leaving any user-added files alone. */
1486
1891
  export const MANIFEST_FILENAME = '.contractkit-bruno-manifest.json';
1487
1892
  &nbsp;
1893
+ /**
1894
+ * Bumped whenever the codegen output shape changes in a way that should bust
1895
+ * every per-op fingerprint. Mixed into the per-op fingerprint so a plugin
1896
+ * upgrade forces full regeneration even when source `.ck` files are unchanged.
1897
+ */
1898
+ export const BRUNO_CODEGEN_VERSION = '1';
1899
+ &nbsp;
1488
1900
  /** Subset of a security scheme sufficient for Bruno auth generation (non-HMAC). */
1489
1901
  export interface BrunoSecurityScheme {
1490
1902
  type: string; // "http" | "apiKey" | "oauth2" | "openIdConnect"
@@ -1531,28 +1943,76 @@ export interface OpenCollectionOptions {
1531
1943
  environments?: Record&lt;string, Record&lt;string, unknown&gt;&gt;;
1532
1944
  }
1533
1945
  &nbsp;
1946
+ /** Per-operation bookkeeping computed up front: where the file lives, what to call it, and the YAML inputs needed to render or fingerprint it. */
1947
+ interface OpEntry {
1948
+ /** Stable identifier across runs — `&lt;file&gt;::&lt;METHOD&gt; &lt;path&gt;`. */
1949
+ opKey: string;
1950
+ /** Output path relative to the collection root (e.g. `users/get-user.yml`). */
1951
+ relativePath: string;
1952
+ /** Display name used inside the YAML `info:` block (alphabetized within its folder). */
1953
+ requestName: string;
1954
+ /** 1-based sequence within the request's containing folder, drives Bruno's UI ordering. */
1955
+ seq: number;
1956
+ route: OpRouteNode;
1957
+ op: OpOperationNode;
1958
+ root: OpRootNode;
1959
+ }
1960
+ &nbsp;
1961
+ /**
1962
+ * @deprecated Use {@link IncrementalManifest} from `@contractkit/core`. Re-exported here for backwards compatibility.
1963
+ */
1964
+ export type BrunoManifest = IncrementalManifest;
1965
+ &nbsp;
1966
+ /** Result of {@link generateOpenCollectionIncremental}. Renamed `skippedOpCount` for Bruno-specific clarity but otherwise the shared {@link IncrementalResultBase}. */
1967
+ export interface IncrementalResult extends Omit&lt;IncrementalResultBase, 'skippedUnitCount'&gt; {
1968
+ /** Number of ops whose codegen was skipped because their fingerprint matched. */
1969
+ skippedOpCount: number;
1970
+ }
1971
+ &nbsp;
1534
1972
  /**
1535
1973
  * Generates an OpenCollection (https://spec.opencollection.com/) API collection
1536
1974
  * from a set of operation roots. Produces opencollection.yml, an environment
1537
1975
  * file, and one .yml request file per operation.
1976
+ *
1977
+ * This is the full-regeneration entry point — every file is rebuilt from scratch.
1978
+ * For cache-aware incremental builds, use {@link generateOpenCollectionIncremental}.
1538
1979
  */
1539
1980
  export function generateOpenCollection(roots: OpRootNode[], options: OpenCollectionOptions): OpenCollectionFile[] {
1540
- const files: OpenCollectionFile[] = [];
1981
+ const result = generateOpenCollectionIncremental(roots, options, emptyManifest());
1982
+ return result.filesToWrite;
1983
+ }
1541
1984
  &nbsp;
1985
+ /**
1986
+ * Cache-aware variant of {@link generateOpenCollection}. Skips re-rendering YAML
1987
+ * for any op whose fingerprint matches the entry in `prevManifest`. The caller is
1988
+ * responsible for emitting `filesToWrite`, deleting `deletedPaths`, and persisting
1989
+ * `manifest` so the next run can match against it.
1990
+ *
1991
+ * Global files (collection root, env files, folder.yml) are always regenerated —
1992
+ * they're cheap and depend on options the manifest doesn't fingerprint.
1993
+ */
1994
+ export function generateOpenCollectionIncremental(
1995
+ roots: OpRootNode[],
1996
+ options: OpenCollectionOptions,
1997
+ prevManifest: IncrementalManifest,
1998
+ fileExists: (relativePath: string) =&gt; boolean = () =&gt; true,
1999
+ ): IncrementalResult {
1542
2000
  const modelMap = buildModelMap(options.contractRoots ?? []);
1543
2001
  const authOpts = options.auth;
1544
2002
  const defaultScheme = authOpts?.defaultScheme ? authOpts.schemes?.[authOpts.defaultScheme] : undefined;
1545
2003
  const randomExamples = options.randomExamples ?? false;
1546
2004
  const includeInternal = options.includeInternal ?? true;
1547
2005
  &nbsp;
1548
- files.push({ relativePath: 'opencollection.yml', content: generateCollectionRoot(options.collectionName, defaultScheme) });
2006
+ // ── Global files (collection root + env files + folder.yml per area/subarea) ──
2007
+ const globalFiles: OpenCollectionFile[] = [];
2008
+ globalFiles.push({
2009
+ relativePath: 'opencollection.yml',
2010
+ content: generateCollectionRoot(options.collectionName, defaultScheme),
2011
+ });
1549
2012
  for (const envFile of generateEnvFiles(options.environments, defaultScheme)) {
1550
- files.push(envFile);
2013
+ globalFiles.push(envFile);
1551
2014
  }
1552
- // Manifest is appended at the end so it lists every generated path including itself.
1553
2015
  &nbsp;
1554
- // Roots are sorted by their top-level folder display name (then by subarea) so the
1555
- // emitted `seq:` numbers — which drive Bruno's UI ordering — line up alphabetically.
1556
2016
  const sortedRoots = [...roots].sort((a, b) =&gt; {
1557
2017
  const aArea = a.meta['area'] ?? deriveFolderName(a.file);
1558
2018
  const bArea = b.meta['area'] ?? deriveFolderName(b.file);
@@ -1561,12 +2021,12 @@ export function generateOpenCollection(roots: OpRootNode[], options: OpenCollect
1561
2021
  <span class="cstat-no" title="statement not covered" > return (a.meta['subarea'] ?? '').localeCompare(b.meta['subarea'] ?? <span class="branch-1 cbranch-no" title="branch not covered" >'');</span></span>
1562
2022
  });
1563
2023
  &nbsp;
2024
+ const units: IncrementalUnit[] = [];
1564
2025
  for (let rootIdx = 0; rootIdx &lt; sortedRoots.length; rootIdx++) {
1565
2026
  const root = sortedRoots[rootIdx]!;
1566
2027
  const folder = root.meta['area'] ? slugifyName(root.meta['area']) : deriveFolderName(root.file);
1567
2028
  const displayName = (root.meta['area'] ?? folder).charAt(0).toUpperCase() + (root.meta['area'] ?? folder).slice(1);
1568
- &nbsp;
1569
- files.push({ relativePath: `${folder}/folder.yml`, content: generateFolderFile(displayName, rootIdx + 1) });
2029
+ globalFiles.push({ relativePath: `${folder}/folder.yml`, content: generateFolderFile(displayName, rootIdx + 1) });
1570
2030
  &nbsp;
1571
2031
  const subarea = root.meta['subarea'];
1572
2032
  const subareaSlug = subarea ? slugifyName(subarea) : undefined;
@@ -1574,52 +2034,180 @@ export function generateOpenCollection(roots: OpRootNode[], options: OpenCollect
1574
2034
  &nbsp;
1575
2035
  if (subareaSlug) {
1576
2036
  const subareaDisplayName = subarea!.charAt(0).toUpperCase() + subarea!.slice(1);
1577
- files.push({ relativePath: `${requestDir}/folder.yml`, content: generateFolderFile(subareaDisplayName, 1) });
2037
+ globalFiles.push({ relativePath: `${requestDir}/folder.yml`, content: generateFolderFile(subareaDisplayName, 1) });
1578
2038
  }
1579
2039
  &nbsp;
1580
- // Flatten and alphabetize within this folder before assigning `seq:`.
1581
- const requests: Array&lt;{ route: typeof root.routes[number]; op: typeof root.routes[number]['operations'][number]; requestName: string }&gt; = [];
1582
- for (const route of root.routes) {
1583
- for (const op of route.operations) {
1584
- if (!includeInternal &amp;&amp; resolveModifiers(route, op).includes('internal')) continue;
1585
- requests.push({ route, op, requestName: op.name ?? route.path });
1586
- }
2040
+ for (const entry of buildOpEntries(root, requestDir, includeInternal)) {
2041
+ units.push({
2042
+ key: entry.opKey,
2043
+ fingerprint: computeOpFingerprint(entry, modelMap, defaultScheme, randomExamples),
2044
+ render: () =&gt; [renderOpFile(entry, modelMap, defaultScheme, randomExamples)],
2045
+ });
1587
2046
  }
1588
- requests.sort((a, b) =&gt; a.requestName.localeCompare(b.requestName));
1589
- &nbsp;
1590
- let seq = 1;
1591
- for (const { route, op, requestName } of requests) {
1592
- const fileName = op.name ? `${slugifyName(op.name)}.yml` : `${op.method}-${sanitizePath(route.path)}.yml`;
1593
- let content = generateRequestFile(route, op, requestName, seq, modelMap, root, defaultScheme, randomExamples);
1594
- const pluginOverride = op.pluginFiles?.['bruno'];
1595
- if (pluginOverride !== undefined) {
1596
- content = mergePluginFile(content, pluginOverride);
1597
- }
1598
- files.push({ relativePath: `${requestDir}/${fileName}`, content });
1599
- seq++;
2047
+ }
2048
+ &nbsp;
2049
+ const result = runIncrementalCodegen({
2050
+ codegenVersion: BRUNO_CODEGEN_VERSION,
2051
+ manifestFilename: MANIFEST_FILENAME,
2052
+ prevManifest,
2053
+ globalFiles,
2054
+ units,
2055
+ fileExists,
2056
+ });
2057
+ &nbsp;
2058
+ return {
2059
+ filesToWrite: result.filesToWrite,
2060
+ manifest: result.manifest,
2061
+ deletedPaths: result.deletedPaths,
2062
+ skippedOpCount: result.skippedUnitCount,
2063
+ };
2064
+ }
2065
+ &nbsp;
2066
+ /** Build the ordered, alphabetized op entries for a single root. seq numbers are assigned in alphabetical order so the Bruno UI shows requests sorted by display name. */
2067
+ function buildOpEntries(root: OpRootNode, requestDir: string, includeInternal: boolean): OpEntry[] {
2068
+ const requests: Array&lt;{ route: OpRouteNode; op: OpOperationNode; requestName: string }&gt; = [];
2069
+ for (const route of root.routes) {
2070
+ for (const op of route.operations) {
2071
+ if (!includeInternal &amp;&amp; resolveModifiers(route, op).includes('internal')) continue;
2072
+ requests.push({ route, op, requestName: op.name ?? route.path });
1600
2073
  }
1601
2074
  }
2075
+ requests.sort((a, b) =&gt; a.requestName.localeCompare(b.requestName));
2076
+ &nbsp;
2077
+ const entries: OpEntry[] = [];
2078
+ let seq = 1;
2079
+ for (const { route, op, requestName } of requests) {
2080
+ const fileName = op.name ? `${slugifyName(op.name)}.yml` : `${op.method}-${sanitizePath(route.path)}.yml`;
2081
+ entries.push({
2082
+ opKey: `${root.file}::${op.method.toUpperCase()} ${route.path}`,
2083
+ relativePath: `${requestDir}/${fileName}`,
2084
+ requestName,
2085
+ seq,
2086
+ route,
2087
+ op,
2088
+ root,
2089
+ });
2090
+ seq++;
2091
+ }
2092
+ return entries;
2093
+ }
2094
+ &nbsp;
2095
+ /** Render a single op's request file (including any plugin-extension YAML override). */
2096
+ function renderOpFile(
2097
+ entry: OpEntry,
2098
+ modelMap: Map&lt;string, ModelNode&gt;,
2099
+ defaultScheme: BrunoSecurityScheme | undefined,
2100
+ randomExamples: boolean,
2101
+ ): OpenCollectionFile {
2102
+ let content = generateRequestFile(entry.route, entry.op, entry.requestName, entry.seq, modelMap, entry.root, defaultScheme, randomExamples);
2103
+ const brunoExt = entry.op.pluginExtensions?.['bruno'];
2104
+ const pluginOverride = brunoExt &amp;&amp; typeof brunoExt === 'object' &amp;&amp; !Array.isArray(brunoExt) ? brunoExt['template'] : undefined;
2105
+ if (typeof pluginOverride === 'string') {
2106
+ content = mergePluginFile(content, pluginOverride);
2107
+ }
2108
+ return { relativePath: entry.relativePath, content };
2109
+ }
1602
2110
  &nbsp;
1603
- const trackedPaths = [...files.map(f =&gt; f.relativePath), MANIFEST_FILENAME].sort();
1604
- files.push({
1605
- relativePath: MANIFEST_FILENAME,
1606
- content: JSON.stringify({ files: trackedPaths }, null, 2) + '\n',
2111
+ /** Compute a fingerprint covering every input that affects this op's rendered file. Stable across runs given identical inputs. */
2112
+ function computeOpFingerprint(
2113
+ entry: OpEntry,
2114
+ modelMap: Map&lt;string, ModelNode&gt;,
2115
+ defaultScheme: BrunoSecurityScheme | undefined,
2116
+ randomExamples: boolean,
2117
+ ): string {
2118
+ const referencedModels = collectTransitiveModelRefs(collectOpTypeNodes(entry.route, entry.op), modelMap);
2119
+ const modelSnapshot: Record&lt;string, unknown&gt; = {};
2120
+ for (const name of [...referencedModels].sort()) {
2121
+ const m = modelMap.get(name);
2122
+ if (m) modelSnapshot[name] = m;
2123
+ }
2124
+ // Only include the route fields this op actually depends on. We deliberately exclude
2125
+ // `route.operations` so a change to a sibling op doesn't invalidate this op's cache.
2126
+ const routeShape = {
2127
+ path: entry.route.path,
2128
+ params: entry.route.params ?? null,
2129
+ modifiers: entry.route.modifiers ?? null,
2130
+ security: entry.route.security ?? null,
2131
+ description: entry.route.description ?? null,
2132
+ };
2133
+ return hashFingerprint({
2134
+ v: BRUNO_CODEGEN_VERSION,
2135
+ opKey: entry.opKey,
2136
+ relativePath: entry.relativePath,
2137
+ requestName: entry.requestName,
2138
+ seq: entry.seq,
2139
+ route: routeShape,
2140
+ op: entry.op,
2141
+ rootMeta: entry.root.meta,
2142
+ rootFile: entry.root.file,
2143
+ defaultScheme: defaultScheme ?? null,
2144
+ randomExamples,
2145
+ models: modelSnapshot,
1607
2146
  });
2147
+ }
2148
+ &nbsp;
2149
+ /** Collect every ContractTypeNode that contributes to this op's rendered output. Used as the seed set for transitive model collection in {@link computeOpFingerprint}. */
2150
+ function collectOpTypeNodes(route: OpRouteNode, op: OpOperationNode): ContractTypeNode[] {
2151
+ const out: ContractTypeNode[] = [];
2152
+ pushFromParamSource(route.params, out);
2153
+ pushFromParamSource(op.query, out);
2154
+ pushFromParamSource(op.headers, out);
2155
+ if (op.request) {
2156
+ for (const body of op.request.bodies) out.push(body.bodyType);
2157
+ }
2158
+ for (const resp of op.responses) {
2159
+ if (resp.bodyType) out.push(resp.bodyType);
2160
+ if (resp.headers) {
2161
+ for (const h of resp.headers) out.push(h.type);
2162
+ }
2163
+ }
2164
+ return out;
2165
+ }
2166
+ &nbsp;
2167
+ function pushFromParamSource(src: ParamSource | undefined, out: ContractTypeNode[]): void {
2168
+ if (!src) return;
2169
+ if (src.kind === 'params') {
2170
+ for (const n of src.nodes) out.push(n.type);
2171
+ } else if (src.kind === 'ref') {
2172
+ out.push({ kind: 'ref', name: src.name } as ContractTypeNode);
2173
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="else path not taken" >E</span>if (src.kind === 'type') {</span>
2174
+ <span class="cstat-no" title="statement not covered" > out.push(src.node);</span>
2175
+ }
2176
+ }
1608
2177
  &nbsp;
1609
- return files;
2178
+ /** Empty-state manifest, used when none has been written yet (or when the cache is being bypassed). */
2179
+ export function emptyManifest(): IncrementalManifest {
2180
+ return emptyIncrementalManifest(BRUNO_CODEGEN_VERSION);
1610
2181
  }
1611
2182
  &nbsp;
1612
- /** Parse a previously-written manifest. Returns the list of relative paths to clean up. Returns [] if missing or unreadable so a stale/garbled manifest never blocks regeneration. */
1613
- export function parseManifest(content: string): string[] {
2183
+ /**
2184
+ * Parse a previously-written manifest. Accepts both v1 (`{ files: string[] }`) and v2
2185
+ * (full {@link IncrementalManifest}) shapes. v1 manifests are returned with an empty
2186
+ * `units` map so the next run treats every op as a cache miss while still cleaning up
2187
+ * the tracked file list.
2188
+ *
2189
+ * Returns an empty manifest on any parse error so a stale/garbled file never blocks
2190
+ * regeneration.
2191
+ */
2192
+ export function parseManifest(content: string): IncrementalManifest {
2193
+ const parsed = parseIncrementalManifest(content);
2194
+ // The shared parser handles v2. If v2 parsing produced an empty manifest, fall
2195
+ // through to a v1 shape ({ files: [...] }) and migrate it for cleanup purposes.
2196
+ if (parsed.files.length &gt; 0 || Object.keys(parsed.units).length &gt; 0) return parsed;
1614
2197
  try {
1615
- const parsed = JSON.parse(content);
1616
- if (Array.isArray(parsed?.files) &amp;&amp; parsed.files.every((f: unknown) =&gt; typeof f === 'string')) {
1617
- return parsed.files as string[];
2198
+ const raw = JSON.parse(content);
2199
+ if (Array.isArray(raw?.files) &amp;&amp; raw.files.every((f: unknown) =&gt; typeof f === 'string')) {
2200
+ return {
2201
+ version: INCREMENTAL_MANIFEST_VERSION,
2202
+ codegenVersion: '',
2203
+ files: raw.files as string[],
2204
+ units: {},
2205
+ };
1618
2206
  }
1619
2207
  } catch {
1620
2208
  // fall through
1621
2209
  }
1622
- return [];
2210
+ return emptyManifest();
1623
2211
  }
1624
2212
  &nbsp;
1625
2213
  // ─── Plugin file merge ─────────────────────────────────────────────────────
@@ -2167,7 +2755,7 @@ function yamlString(value: string): string {
2167
2755
  <div class='footer quiet pad2 space-top1 center small'>
2168
2756
  Code coverage generated by
2169
2757
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2170
- at 2026-05-01T19:55:27.966Z
2758
+ at 2026-05-07T11:09:13.542Z
2171
2759
  </div>
2172
2760
  <script src="../prettify.js"></script>
2173
2761
  <script>