unageanu-jiji 1.1.4 → 1.2.1

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.
Files changed (233) hide show
  1. data/ChangeLog +24 -1
  2. data/README +0 -0
  3. data/base/shared_lib/moving_average.rb +34 -33
  4. data/base/shared_lib/system/cross.rb +76 -0
  5. data/base/shared_lib/system/position_manager.rb +160 -0
  6. data/base/shared_lib/system/signal.rb +347 -0
  7. data/html/css/datatable.css +4 -4
  8. data/html/css/default.css +57 -5
  9. data/html/css/treeview.css +205 -0
  10. data/html/img/bin_closed.png +0 -0
  11. data/html/img/bin_empty.png +0 -0
  12. data/html/img/button_add_small.gif +0 -0
  13. data/html/img/button_add_small_gray.gif +0 -0
  14. data/html/img/button_add_small_over.gif +0 -0
  15. data/html/img/button_mkcol.gif +0 -0
  16. data/html/img/button_mkcol_gray.gif +0 -0
  17. data/html/img/button_mkcol_over.gif +0 -0
  18. data/html/img/button_remove_small.gif +0 -0
  19. data/html/img/button_remove_small_gray.gif +0 -0
  20. data/html/img/button_remove_small_over.gif +0 -0
  21. data/html/img/button_rename.gif +0 -0
  22. data/html/img/button_rename_gray.gif +0 -0
  23. data/html/img/button_rename_over.gif +0 -0
  24. data/html/img/control_play.png +0 -0
  25. data/html/img/control_play_blue.png +0 -0
  26. data/html/img/folder.png +0 -0
  27. data/html/img/folder_brick.png +0 -0
  28. data/html/img/folder_user.png +0 -0
  29. data/html/{js/codepress/images → img}/line-numbers.png +0 -0
  30. data/html/img/page_white_ruby.png +0 -0
  31. data/html/img/sidebar_agent_edit.png +0 -0
  32. data/html/img/sidebar_agent_edit_over.png +0 -0
  33. data/html/img/sidebar_agent_edit_s.png +0 -0
  34. data/html/img/yui/treeview-sprite.gif +0 -0
  35. data/html/index.html +34 -18
  36. data/html/js/agent-editor/agent-editor-page.js +324 -0
  37. data/html/js/agent-editor/agent-editor.js +363 -0
  38. data/html/js/agent-editor/agent-list-tree.js +251 -0
  39. data/html/js/agent-selector.js +23 -28
  40. data/html/js/app.js +63 -91
  41. data/html/js/bt-create-page.js +25 -19
  42. data/html/js/container-min.js +1 -1
  43. data/html/js/container.js +944 -0
  44. data/html/js/edit_area/autocompletion.js +11 -13
  45. data/html/js/edit_area/edit_area.css +79 -40
  46. data/html/js/edit_area/edit_area.js +255 -226
  47. data/html/js/edit_area/edit_area_compressor.php +4 -4
  48. data/html/js/edit_area/edit_area_full.gz +0 -0
  49. data/html/js/edit_area/edit_area_full.js +31 -31
  50. data/html/js/edit_area/edit_area_full_with_plugins.gz +0 -0
  51. data/html/js/edit_area/edit_area_full_with_plugins.js +31 -31
  52. data/html/js/edit_area/edit_area_functions.js +448 -341
  53. data/html/js/edit_area/edit_area_loader.js +409 -397
  54. data/html/js/edit_area/elements_functions.js +120 -123
  55. data/html/js/edit_area/highlight.js +305 -197
  56. data/html/js/edit_area/images/goto.png +0 -0
  57. data/html/js/edit_area/images/help.png +0 -0
  58. data/html/js/edit_area/images/redo.png +0 -0
  59. data/html/js/edit_area/images/save.png +0 -0
  60. data/html/js/edit_area/images/search.png +0 -0
  61. data/html/js/edit_area/images/undo.png +0 -0
  62. data/html/js/edit_area/images/word_wrap.gif +0 -0
  63. data/html/js/edit_area/keyboard.js +5 -5
  64. data/html/js/edit_area/langs/bg.js +73 -0
  65. data/html/js/edit_area/langs/cs.js +2 -0
  66. data/html/js/edit_area/langs/de.js +2 -0
  67. data/html/js/edit_area/langs/dk.js +2 -0
  68. data/html/js/edit_area/langs/en.js +2 -0
  69. data/html/js/edit_area/langs/eo.js +2 -0
  70. data/html/js/edit_area/langs/es.js +2 -0
  71. data/html/js/edit_area/langs/fi.js +67 -0
  72. data/html/js/edit_area/langs/fr.js +2 -0
  73. data/html/js/edit_area/langs/hr.js +2 -0
  74. data/html/js/edit_area/langs/it.js +2 -0
  75. data/html/js/edit_area/langs/ja.js +2 -0
  76. data/html/js/edit_area/langs/mk.js +2 -0
  77. data/html/js/edit_area/langs/nl.js +2 -0
  78. data/html/js/edit_area/langs/pl.js +2 -0
  79. data/html/js/edit_area/langs/pt.js +2 -0
  80. data/html/js/edit_area/langs/ru.js +2 -0
  81. data/html/js/edit_area/langs/sk.js +2 -0
  82. data/html/js/edit_area/langs/zh.js +67 -0
  83. data/html/js/edit_area/manage_area.js +362 -205
  84. data/html/js/edit_area/plugins/charmap/langs/bg.js +12 -0
  85. data/html/js/edit_area/plugins/charmap/langs/zh.js +6 -0
  86. data/html/js/edit_area/plugins/test/langs/bg.js +10 -0
  87. data/html/js/edit_area/plugins/test/langs/zh.js +4 -0
  88. data/html/js/edit_area/reg_syntax/java.js +56 -0
  89. data/html/js/edit_area/reg_syntax/ruby.js +9 -9
  90. data/html/js/edit_area/reg_syntax.js +15 -13
  91. data/html/js/edit_area/regexp.js +36 -32
  92. data/html/js/edit_area/resize_area.js +43 -47
  93. data/html/js/edit_area/search_replace.js +29 -29
  94. data/html/js/edit_area/template.html +6 -4
  95. data/html/js/json-broker-client.js +23 -17
  96. data/html/js/result-page.js +107 -57
  97. data/html/js/rt-setting-page.js +38 -15
  98. data/html/js/sidebar.js +41 -27
  99. data/html/js/templates.js +167 -32
  100. data/html/js/utils.js +143 -7
  101. data/html/js/yui/treeview.js +3671 -0
  102. data/html/swf/chart.swf +0 -0
  103. data/html/test/agent_editor_spec.js +815 -0
  104. data/html/test/index.html +40 -0
  105. data/html/test/jsspec/JSSpec.css +224 -0
  106. data/html/test/jsspec/JSSpec.js +1549 -0
  107. data/html/test/jsspec/diff_match_patch.js +1 -0
  108. data/html/test/utils_spec.js +111 -0
  109. data/lib/jiji/agent/agent.rb +69 -12
  110. data/lib/jiji/agent/agent_manager.rb +18 -12
  111. data/lib/jiji/agent/agent_registry.rb +35 -121
  112. data/lib/jiji/collector.rb +16 -6
  113. data/lib/jiji/command.rb +46 -5
  114. data/lib/jiji/dao/file_system_dao.rb +158 -0
  115. data/lib/jiji/dao/timed_data_dao.rb +2 -0
  116. data/lib/jiji/dao/trade_result_dao.rb +1 -1
  117. data/lib/jiji/error.rb +24 -8
  118. data/lib/jiji/migration/migrator1_2_0.rb +67 -0
  119. data/lib/jiji/models.rb +82 -24
  120. data/lib/jiji/operator.rb +55 -51
  121. data/lib/jiji/output.rb +85 -29
  122. data/lib/jiji/output_manager.rb +84 -0
  123. data/lib/jiji/plugin/embedded/single_click_client.rb +2 -2
  124. data/lib/jiji/plugin/securities_plugin.rb +0 -1
  125. data/lib/jiji/process.rb +229 -208
  126. data/lib/jiji/process_manager.rb +190 -96
  127. data/lib/jiji/registry.rb +87 -19
  128. data/lib/jiji/server.rb +1 -0
  129. data/lib/jiji/service/agent_service.rb +147 -48
  130. data/lib/jiji/service/output_service.rb +37 -17
  131. data/lib/jiji/service/process_service.rb +3 -5
  132. data/lib/jiji/service/trade_result_service.rb +4 -5
  133. data/lib/jiji/util/file_lock.rb +4 -4
  134. data/lib/jiji/util/include_proxy.rb +17 -0
  135. data/lib/jiji/util/json_broker.rb +6 -4
  136. data/lib/jiji/util/util.rb +1 -1
  137. data/swf/chart/fx/chart/Chart.as +7 -0
  138. data/swf/chart/fx/chart/ui/graph/GraphManager.as +15 -2
  139. data/test/ProcessTest/agents/foo.rb +10 -0
  140. data/test/ProcessTest/conf/configuration.yaml +3 -0
  141. data/test/agent/agent_tests.rb +10 -0
  142. data/test/agent/test_AgentManager.rb +28 -12
  143. data/test/agent/test_AgentRegistry.rb +194 -99
  144. data/test/agent/test_PeriodicallyAgent.rb +1 -2
  145. data/test/agent/test_Permitter.rb +1 -2
  146. data/test/all_tests.rb +7 -19
  147. data/test/dao/dao_tests.rb +9 -0
  148. data/test/dao/test_FileSystemDao.rb +431 -0
  149. data/test/dao/test_RateDao.rb +5 -7
  150. data/test/dao/test_TradeResultDao.rb +1 -2
  151. data/test/migration/migration_tests.rb +10 -0
  152. data/test/migration/migrator1_2_0test_data/basic/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  153. data/test/migration/migrator1_2_0test_data/basic/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  154. data/test/migration/migrator1_2_0test_data/basic/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  155. data/test/migration/migrator1_2_0test_data/basic/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  156. data/test/migration/migrator1_2_0test_data/basic/props.yaml +85 -0
  157. data/test/migration/migrator1_2_0test_data/illegal_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  158. data/test/migration/migrator1_2_0test_data/illegal_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  159. data/test/migration/migrator1_2_0test_data/illegal_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  160. data/test/migration/migrator1_2_0test_data/illegal_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  161. data/test/migration/migrator1_2_0test_data/illegal_props/props.yaml +1 -0
  162. data/test/migration/migrator1_2_0test_data/no_outs/props.yaml +85 -0
  163. data/test/migration/migrator1_2_0test_data/no_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  164. data/test/migration/migrator1_2_0test_data/no_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  165. data/test/migration/migrator1_2_0test_data/no_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  166. data/test/migration/migrator1_2_0test_data/no_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  167. data/test/migration/test_Migrator.rb +1 -1
  168. data/test/migration/test_Migrator1_0_3.rb +1 -1
  169. data/test/migration/test_Migrator1_1_0.rb +1 -1
  170. data/test/migration/test_Migrator1_2_0.rb +94 -0
  171. data/test/plugin/embedded/test_SingleClickClient.rb +1 -2
  172. data/test/plugin/plugin_tests.rb +8 -0
  173. data/test/plugin/test_Loader.rb +1 -1
  174. data/test/shared/rate.csv +144 -0
  175. data/test/shared/shared_tests.rb +9 -0
  176. data/test/shared/test_Cross.rb +144 -0
  177. data/test/shared/test_PositionManager.rb +285 -0
  178. data/test/shared/test_Signal.rb +65 -0
  179. data/test/test_Output.rb +28 -21
  180. data/test/test_OutputManager.rb +162 -0
  181. data/test/test_Output_registry.rb +6 -17
  182. data/test/test_Process.rb +434 -222
  183. data/test/test_ProcessManager.rb +458 -101
  184. data/test/test_utils.rb +71 -8
  185. data/test/util/test_BlockToSession.rb +1 -2
  186. data/test/util/test_CSV.rb +1 -2
  187. data/test/util/test_SynchronizeInterceptor.rb +1 -2
  188. data/test/util/util_tests.rb +9 -0
  189. metadata +127 -47
  190. data/html/js/agent-editor-page.js +0 -440
  191. data/html/js/codepress/codepress.css +0 -21
  192. data/html/js/codepress/codepress.html +0 -35
  193. data/html/js/codepress/codepress.js +0 -138
  194. data/html/js/codepress/engines/gecko.js +0 -293
  195. data/html/js/codepress/engines/khtml.js +0 -0
  196. data/html/js/codepress/engines/msie.js +0 -304
  197. data/html/js/codepress/engines/older.js +0 -0
  198. data/html/js/codepress/engines/opera.js +0 -260
  199. data/html/js/codepress/images/line-numbers.gif +0 -0
  200. data/html/js/codepress/index.html +0 -443
  201. data/html/js/codepress/languages/asp.css +0 -71
  202. data/html/js/codepress/languages/asp.js +0 -117
  203. data/html/js/codepress/languages/autoit.css +0 -13
  204. data/html/js/codepress/languages/autoit.js +0 -32
  205. data/html/js/codepress/languages/csharp.css +0 -9
  206. data/html/js/codepress/languages/csharp.js +0 -25
  207. data/html/js/codepress/languages/css.css +0 -10
  208. data/html/js/codepress/languages/css.js +0 -23
  209. data/html/js/codepress/languages/generic.css +0 -9
  210. data/html/js/codepress/languages/generic.js +0 -25
  211. data/html/js/codepress/languages/html.css +0 -13
  212. data/html/js/codepress/languages/html.js +0 -59
  213. data/html/js/codepress/languages/java.css +0 -7
  214. data/html/js/codepress/languages/java.js +0 -24
  215. data/html/js/codepress/languages/javascript.css +0 -8
  216. data/html/js/codepress/languages/javascript.js +0 -30
  217. data/html/js/codepress/languages/perl.css +0 -11
  218. data/html/js/codepress/languages/perl.js +0 -27
  219. data/html/js/codepress/languages/php.css +0 -12
  220. data/html/js/codepress/languages/php.js +0 -61
  221. data/html/js/codepress/languages/ruby.css +0 -10
  222. data/html/js/codepress/languages/ruby.js +0 -26
  223. data/html/js/codepress/languages/sql.css +0 -10
  224. data/html/js/codepress/languages/sql.js +0 -30
  225. data/html/js/codepress/languages/text.css +0 -5
  226. data/html/js/codepress/languages/text.js +0 -9
  227. data/html/js/codepress/languages/vbscript.css +0 -71
  228. data/html/js/codepress/languages/vbscript.js +0 -117
  229. data/html/js/codepress/languages/xsl.css +0 -15
  230. data/html/js/codepress/languages/xsl.js +0 -103
  231. data/html/js/codepress/license.txt +0 -458
  232. data/html/js/edit_area/images/Thumbs.db +0 -0
  233. data/test/plugin/test_gem/a/lib/jiji_plugin_test.rb +0 -6
@@ -0,0 +1 @@
1
+ function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff_DualThreshold=32;this.Match_Balance=0.5;this.Match_Threshold=0.5;this.Match_MinLength=100;this.Match_MaxLength=1000;this.Patch_Margin=4;function getMaxBits(){var maxbits=0;var oldi=1;var newi=2;while(oldi!=newi){maxbits++;oldi=newi;newi=newi<<1}return maxbits}this.Match_MaxBits=getMaxBits()}var DIFF_DELETE=-1;var DIFF_INSERT=1;var DIFF_EQUAL=0;diff_match_patch.prototype.diff_main=function(text1,text2,opt_checklines){if(text1==text2){return[[DIFF_EQUAL,text1]]}if(typeof opt_checklines=='undefined'){opt_checklines=true}var checklines=opt_checklines;var commonlength=this.diff_commonPrefix(text1,text2);var commonprefix=text1.substring(0,commonlength);text1=text1.substring(commonlength);text2=text2.substring(commonlength);commonlength=this.diff_commonSuffix(text1,text2);var commonsuffix=text1.substring(text1.length-commonlength);text1=text1.substring(0,text1.length-commonlength);text2=text2.substring(0,text2.length-commonlength);var diffs=this.diff_compute(text1,text2,checklines);if(commonprefix){diffs.unshift([DIFF_EQUAL,commonprefix])}if(commonsuffix){diffs.push([DIFF_EQUAL,commonsuffix])}this.diff_cleanupMerge(diffs);return diffs};diff_match_patch.prototype.diff_compute=function(text1,text2,checklines){var diffs;if(!text1){return[[DIFF_INSERT,text2]]}if(!text2){return[[DIFF_DELETE,text1]]}var longtext=text1.length>text2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;var i=longtext.indexOf(shorttext);if(i!=-1){diffs=[[DIFF_INSERT,longtext.substring(0,i)],[DIFF_EQUAL,shorttext],[DIFF_INSERT,longtext.substring(i+shorttext.length)]];if(text1.length>text2.length){diffs[0][0]=diffs[2][0]=DIFF_DELETE}return diffs}longtext=shorttext=null;var hm=this.diff_halfMatch(text1,text2);if(hm){var text1_a=hm[0];var text1_b=hm[1];var text2_a=hm[2];var text2_b=hm[3];var mid_common=hm[4];var diffs_a=this.diff_main(text1_a,text2_a,checklines);var diffs_b=this.diff_main(text1_b,text2_b,checklines);return diffs_a.concat([[DIFF_EQUAL,mid_common]],diffs_b)}if(checklines&&text1.length+text2.length<250){checklines=false}var linearray;if(checklines){var a=this.diff_linesToChars(text1,text2);text1=a[0];text2=a[1];linearray=a[2]}diffs=this.diff_map(text1,text2);if(!diffs){diffs=[[DIFF_DELETE,text1],[DIFF_INSERT,text2]]}if(checklines){this.diff_charsToLines(diffs,linearray);this.diff_cleanupSemantic(diffs);diffs.push([DIFF_EQUAL,'']);var pointer=0;var count_delete=0;var count_insert=0;var text_delete='';var text_insert='';while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_INSERT){count_insert++;text_insert+=diffs[pointer][1]}else if(diffs[pointer][0]==DIFF_DELETE){count_delete++;text_delete+=diffs[pointer][1]}else{if(count_delete>=1&&count_insert>=1){var a=this.diff_main(text_delete,text_insert,false);diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert);pointer=pointer-count_delete-count_insert;for(var j=a.length-1;j>=0;j--){diffs.splice(pointer,0,a[j])}pointer=pointer+a.length}count_insert=0;count_delete=0;text_delete='';text_insert=''}pointer++}diffs.pop()}return diffs};diff_match_patch.prototype.diff_linesToChars=function(text1,text2){var linearray=[];var linehash={};linearray.push('');function diff_linesToCharsMunge(text){var chars='';while(text){var i=text.indexOf('\n');if(i==-1){i=text.length}var line=text.substring(0,i+1);text=text.substring(i+1);if(linehash.hasOwnProperty?linehash.hasOwnProperty(line):(linehash[line]!==undefined)){chars+=String.fromCharCode(linehash[line])}else{linearray.push(line);linehash[line]=linearray.length-1;chars+=String.fromCharCode(linearray.length-1)}}return chars}var chars1=diff_linesToCharsMunge(text1);var chars2=diff_linesToCharsMunge(text2);return[chars1,chars2,linearray]};diff_match_patch.prototype.diff_charsToLines=function(diffs,linearray){for(var x=0;x<diffs.length;x++){var chars=diffs[x][1];var text=[];for(var y=0;y<chars.length;y++){text.push(linearray[chars.charCodeAt(y)])}diffs[x][1]=text.join('')}};diff_match_patch.prototype.diff_map=function(text1,text2){var ms_end=(new Date()).getTime()+this.Diff_Timeout*1000;var max_d=text1.length+text2.length-1;var doubleEnd=this.Diff_DualThreshold*2<max_d;var v_map1=[];var v_map2=[];var v1={};var v2={};v1[1]=0;v2[1]=0;var x,y;var footstep;var footsteps={};var done=false;var hasOwnProperty=!!(footsteps.hasOwnProperty);var front=(text1.length+text2.length)%2;for(var d=0;d<max_d;d++){if(this.Diff_Timeout>0&&(new Date()).getTime()>ms_end){return null}v_map1[d]={};for(var k=-d;k<=d;k+=2){if(k==-d||k!=d&&v1[k-1]<v1[k+1]){x=v1[k+1]}else{x=v1[k-1]+1}y=x-k;if(doubleEnd){footstep=x+','+y;if(front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(!front){footsteps[footstep]=d}}while(!done&&x<text1.length&&y<text2.length&&text1.charAt(x)==text2.charAt(y)){x++;y++;if(doubleEnd){footstep=x+','+y;if(front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(!front){footsteps[footstep]=d}}}v1[k]=x;v_map1[d][x+','+y]=true;if(x==text1.length&&y==text2.length){return this.diff_path1(v_map1,text1,text2)}else if(done){v_map2=v_map2.slice(0,footsteps[footstep]+1);var a=this.diff_path1(v_map1,text1.substring(0,x),text2.substring(0,y));return a.concat(this.diff_path2(v_map2,text1.substring(x),text2.substring(y)))}}if(doubleEnd){v_map2[d]={};for(var k=-d;k<=d;k+=2){if(k==-d||k!=d&&v2[k-1]<v2[k+1]){x=v2[k+1]}else{x=v2[k-1]+1}y=x-k;footstep=(text1.length-x)+','+(text2.length-y);if(!front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(front){footsteps[footstep]=d}while(!done&&x<text1.length&&y<text2.length&&text1.charAt(text1.length-x-1)==text2.charAt(text2.length-y-1)){x++;y++;footstep=(text1.length-x)+','+(text2.length-y);if(!front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(front){footsteps[footstep]=d}}v2[k]=x;v_map2[d][x+','+y]=true;if(done){v_map1=v_map1.slice(0,footsteps[footstep]+1);var a=this.diff_path1(v_map1,text1.substring(0,text1.length-x),text2.substring(0,text2.length-y));return a.concat(this.diff_path2(v_map2,text1.substring(text1.length-x),text2.substring(text2.length-y)))}}}}return null};diff_match_patch.prototype.diff_path1=function(v_map,text1,text2){var path=[];var x=text1.length;var y=text2.length;var last_op=null;for(var d=v_map.length-2;d>=0;d--){while(1){if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty((x-1)+','+y):(v_map[d][(x-1)+','+y]!==undefined)){x--;if(last_op===DIFF_DELETE){path[0][1]=text1.charAt(x)+path[0][1]}else{path.unshift([DIFF_DELETE,text1.charAt(x)])}last_op=DIFF_DELETE;break}else if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty(x+','+(y-1)):(v_map[d][x+','+(y-1)]!==undefined)){y--;if(last_op===DIFF_INSERT){path[0][1]=text2.charAt(y)+path[0][1]}else{path.unshift([DIFF_INSERT,text2.charAt(y)])}last_op=DIFF_INSERT;break}else{x--;y--;if(last_op===DIFF_EQUAL){path[0][1]=text1.charAt(x)+path[0][1]}else{path.unshift([DIFF_EQUAL,text1.charAt(x)])}last_op=DIFF_EQUAL}}}return path};diff_match_patch.prototype.diff_path2=function(v_map,text1,text2){var path=[];var x=text1.length;var y=text2.length;var last_op=null;for(var d=v_map.length-2;d>=0;d--){while(1){if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty((x-1)+','+y):(v_map[d][(x-1)+','+y]!==undefined)){x--;if(last_op===DIFF_DELETE){path[path.length-1][1]+=text1.charAt(text1.length-x-1)}else{path.push([DIFF_DELETE,text1.charAt(text1.length-x-1)])}last_op=DIFF_DELETE;break}else if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty(x+','+(y-1)):(v_map[d][x+','+(y-1)]!==undefined)){y--;if(last_op===DIFF_INSERT){path[path.length-1][1]+=text2.charAt(text2.length-y-1)}else{path.push([DIFF_INSERT,text2.charAt(text2.length-y-1)])}last_op=DIFF_INSERT;break}else{x--;y--;if(last_op===DIFF_EQUAL){path[path.length-1][1]+=text1.charAt(text1.length-x-1)}else{path.push([DIFF_EQUAL,text1.charAt(text1.length-x-1)])}last_op=DIFF_EQUAL}}}return path};diff_match_patch.prototype.diff_commonPrefix=function(text1,text2){if(!text1||!text2||text1.charCodeAt(0)!==text2.charCodeAt(0)){return 0}var pointermin=0;var pointermax=Math.min(text1.length,text2.length);var pointermid=pointermax;var pointerstart=0;while(pointermin<pointermid){if(text1.substring(pointerstart,pointermid)==text2.substring(pointerstart,pointermid)){pointermin=pointermid;pointerstart=pointermin}else{pointermax=pointermid}pointermid=Math.floor((pointermax-pointermin)/2+pointermin)}return pointermid};diff_match_patch.prototype.diff_commonSuffix=function(text1,text2){if(!text1||!text2||text1.charCodeAt(text1.length-1)!==text2.charCodeAt(text2.length-1)){return 0}var pointermin=0;var pointermax=Math.min(text1.length,text2.length);var pointermid=pointermax;var pointerend=0;while(pointermin<pointermid){if(text1.substring(text1.length-pointermid,text1.length-pointerend)==text2.substring(text2.length-pointermid,text2.length-pointerend)){pointermin=pointermid;pointerend=pointermin}else{pointermax=pointermid}pointermid=Math.floor((pointermax-pointermin)/2+pointermin)}return pointermid};diff_match_patch.prototype.diff_halfMatch=function(text1,text2){var longtext=text1.length>text2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;if(longtext.length<10||shorttext.length<1){return null}var dmp=this;function diff_halfMatchI(longtext,shorttext,i){var seed=longtext.substring(i,i+Math.floor(longtext.length/4));var j=-1;var best_common='';var best_longtext_a,best_longtext_b,best_shorttext_a,best_shorttext_b;while((j=shorttext.indexOf(seed,j+1))!=-1){var prefixLength=dmp.diff_commonPrefix(longtext.substring(i),shorttext.substring(j));var suffixLength=dmp.diff_commonSuffix(longtext.substring(0,i),shorttext.substring(0,j));if(best_common.length<suffixLength+prefixLength){best_common=shorttext.substring(j-suffixLength,j)+shorttext.substring(j,j+prefixLength);best_longtext_a=longtext.substring(0,i-suffixLength);best_longtext_b=longtext.substring(i+prefixLength);best_shorttext_a=shorttext.substring(0,j-suffixLength);best_shorttext_b=shorttext.substring(j+prefixLength)}}if(best_common.length>=longtext.length/2){return[best_longtext_a,best_longtext_b,best_shorttext_a,best_shorttext_b,best_common]}else{return null}}var hm1=diff_halfMatchI(longtext,shorttext,Math.ceil(longtext.length/4));var hm2=diff_halfMatchI(longtext,shorttext,Math.ceil(longtext.length/2));var hm;if(!hm1&&!hm2){return null}else if(!hm2){hm=hm1}else if(!hm1){hm=hm2}else{hm=hm1[4].length>hm2[4].length?hm1:hm2}var text1_a,text1_b,text2_a,text2_b;if(text1.length>text2.length){text1_a=hm[0];text1_b=hm[1];text2_a=hm[2];text2_b=hm[3]}else{text2_a=hm[0];text2_b=hm[1];text1_a=hm[2];text1_b=hm[3]}var mid_common=hm[4];return[text1_a,text1_b,text2_a,text2_b,mid_common]};diff_match_patch.prototype.diff_cleanupSemantic=function(diffs){var changes=false;var equalities=[];var lastequality=null;var pointer=0;var length_changes1=0;var length_changes2=0;while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_EQUAL){equalities.push(pointer);length_changes1=length_changes2;length_changes2=0;lastequality=diffs[pointer][1]}else{length_changes2+=diffs[pointer][1].length;if(lastequality!==null&&(lastequality.length<=length_changes1)&&(lastequality.length<=length_changes2)){diffs.splice(equalities[equalities.length-1],0,[DIFF_DELETE,lastequality]);diffs[equalities[equalities.length-1]+1][0]=DIFF_INSERT;equalities.pop();equalities.pop();pointer=equalities.length?equalities[equalities.length-1]:-1;length_changes1=0;length_changes2=0;lastequality=null;changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}this.diff_cleanupSemanticLossless(diffs)};diff_match_patch.prototype.diff_cleanupSemanticLossless=function(diffs){function diff_cleanupSemanticScore(one,two,three){var whitespace=/\s/;var score=0;if(one.charAt(one.length-1).match(whitespace)||two.charAt(0).match(whitespace)){score++}if(two.charAt(two.length-1).match(whitespace)||three.charAt(0).match(whitespace)){score++}return score}var pointer=1;while(pointer<diffs.length-1){if(diffs[pointer-1][0]==DIFF_EQUAL&&diffs[pointer+1][0]==DIFF_EQUAL){var equality1=diffs[pointer-1][1];var edit=diffs[pointer][1];var equality2=diffs[pointer+1][1];var commonOffset=this.diff_commonSuffix(equality1,edit);if(commonOffset){var commonString=edit.substring(edit.length-commonOffset);equality1=equality1.substring(0,equality1.length-commonOffset);edit=commonString+edit.substring(0,edit.length-commonOffset);equality2=commonString+equality2}var bestEquality1=equality1;var bestEdit=edit;var bestEquality2=equality2;var bestScore=diff_cleanupSemanticScore(equality1,edit,equality2);while(edit.charAt(0)===equality2.charAt(0)){equality1+=edit.charAt(0);edit=edit.substring(1)+equality2.charAt(0);equality2=equality2.substring(1);var score=diff_cleanupSemanticScore(equality1,edit,equality2);if(score>=bestScore){bestScore=score;bestEquality1=equality1;bestEdit=edit;bestEquality2=equality2}}if(diffs[pointer-1][1]!=bestEquality1){diffs[pointer-1][1]=bestEquality1;diffs[pointer][1]=bestEdit;diffs[pointer+1][1]=bestEquality2}}pointer++}};diff_match_patch.prototype.diff_cleanupEfficiency=function(diffs){var changes=false;var equalities=[];var lastequality='';var pointer=0;var pre_ins=false;var pre_del=false;var post_ins=false;var post_del=false;while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_EQUAL){if(diffs[pointer][1].length<this.Diff_EditCost&&(post_ins||post_del)){equalities.push(pointer);pre_ins=post_ins;pre_del=post_del;lastequality=diffs[pointer][1]}else{equalities=[];lastequality=''}post_ins=post_del=false}else{if(diffs[pointer][0]==DIFF_DELETE){post_del=true}else{post_ins=true}if(lastequality&&((pre_ins&&pre_del&&post_ins&&post_del)||((lastequality.length<this.Diff_EditCost/2)&&(pre_ins+pre_del+post_ins+post_del)==3))){diffs.splice(equalities[equalities.length-1],0,[DIFF_DELETE,lastequality]);diffs[equalities[equalities.length-1]+1][0]=DIFF_INSERT;equalities.pop();lastequality='';if(pre_ins&&pre_del){post_ins=post_del=true;equalities=[]}else{equalities.pop();pointer=equalities.length?equalities[equalities.length-1]:-1;post_ins=post_del=false}changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}};diff_match_patch.prototype.diff_cleanupMerge=function(diffs){diffs.push([DIFF_EQUAL,'']);var pointer=0;var count_delete=0;var count_insert=0;var text_delete='';var text_insert='';var commonlength;while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_INSERT){count_insert++;text_insert+=diffs[pointer][1];pointer++}else if(diffs[pointer][0]==DIFF_DELETE){count_delete++;text_delete+=diffs[pointer][1];pointer++}else{if(count_delete!==0||count_insert!==0){if(count_delete!==0&&count_insert!==0){commonlength=this.diff_commonPrefix(text_insert,text_delete);if(commonlength!==0){if((pointer-count_delete-count_insert)>0&&diffs[pointer-count_delete-count_insert-1][0]==DIFF_EQUAL){diffs[pointer-count_delete-count_insert-1][1]+=text_insert.substring(0,commonlength)}else{diffs.splice(0,0,[DIFF_EQUAL,text_insert.substring(0,commonlength)]);pointer++}text_insert=text_insert.substring(commonlength);text_delete=text_delete.substring(commonlength)}commonlength=this.diff_commonSuffix(text_insert,text_delete);if(commonlength!==0){diffs[pointer][1]=text_insert.substring(text_insert.length-commonlength)+diffs[pointer][1];text_insert=text_insert.substring(0,text_insert.length-commonlength);text_delete=text_delete.substring(0,text_delete.length-commonlength)}}if(count_delete===0){diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_INSERT,text_insert])}else if(count_insert===0){diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_DELETE,text_delete])}else{diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_DELETE,text_delete],[DIFF_INSERT,text_insert])}pointer=pointer-count_delete-count_insert+(count_delete?1:0)+(count_insert?1:0)+1}else if(pointer!==0&&diffs[pointer-1][0]==DIFF_EQUAL){diffs[pointer-1][1]+=diffs[pointer][1];diffs.splice(pointer,1)}else{pointer++}count_insert=0;count_delete=0;text_delete='';text_insert=''}}if(diffs[diffs.length-1][1]===''){diffs.pop()}var changes=false;pointer=1;while(pointer<diffs.length-1){if(diffs[pointer-1][0]==DIFF_EQUAL&&diffs[pointer+1][0]==DIFF_EQUAL){if(diffs[pointer][1].substring(diffs[pointer][1].length-diffs[pointer-1][1].length)==diffs[pointer-1][1]){diffs[pointer][1]=diffs[pointer-1][1]+diffs[pointer][1].substring(0,diffs[pointer][1].length-diffs[pointer-1][1].length);diffs[pointer+1][1]=diffs[pointer-1][1]+diffs[pointer+1][1];diffs.splice(pointer-1,1);changes=true}else if(diffs[pointer][1].substring(0,diffs[pointer+1][1].length)==diffs[pointer+1][1]){diffs[pointer-1][1]+=diffs[pointer+1][1];diffs[pointer][1]=diffs[pointer][1].substring(diffs[pointer+1][1].length)+diffs[pointer+1][1];diffs.splice(pointer+1,1);changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}};diff_match_patch.prototype.diff_addIndex=function(diffs){var i=0;for(var x=0;x<diffs.length;x++){diffs[x].push(i);if(diffs[x][0]!==DIFF_DELETE){i+=diffs[x][1].length}}};diff_match_patch.prototype.diff_xIndex=function(diffs,loc){var chars1=0;var chars2=0;var last_chars1=0;var last_chars2=0;var x;for(x=0;x<diffs.length;x++){if(diffs[x][0]!==DIFF_INSERT){chars1+=diffs[x][1].length}if(diffs[x][0]!==DIFF_DELETE){chars2+=diffs[x][1].length}if(chars1>loc){break}last_chars1=chars1;last_chars2=chars2}if(diffs.length!=x&&diffs[x][0]===DIFF_DELETE){return last_chars2}return last_chars2+(loc-last_chars1)};diff_match_patch.prototype.diff_prettyHtml=function(diffs){this.diff_addIndex(diffs);var html=[];for(var x=0;x<diffs.length;x++){var m=diffs[x][0];var t=diffs[x][1];var i=diffs[x][2];t=t.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');t=t.replace(/\n/g,'&para;<BR>');if(m===DIFF_DELETE){html.push('<DEL STYLE="background:#FFE6E6;" TITLE="i=',i,'">',t,'</DEL>')}else if(m===DIFF_INSERT){html.push('<INS STYLE="background:#E6FFE6;" TITLE="i=',i,'">',t,'</INS>')}else{html.push('<SPAN TITLE="i=',i,'">',t,'</SPAN>')}}return html.join('')};diff_match_patch.prototype.diff_text1=function(diffs){var txt=[];for(var x=0;x<diffs.length;x++){if(diffs[x][0]!==DIFF_INSERT){txt.push(diffs[x][1])}}return txt.join('')};diff_match_patch.prototype.diff_text2=function(diffs){var txt=[];for(var x=0;x<diffs.length;x++){if(diffs[x][0]!==DIFF_DELETE){txt.push(diffs[x][1])}}return txt.join('')};diff_match_patch.prototype.diff_toDelta=function(diffs){var txt=[];for(var x=0;x<diffs.length;x++){switch(diffs[x][0]){case DIFF_DELETE:txt.push('-',diffs[x][1].length,'\t');break;case DIFF_EQUAL:txt.push('=',diffs[x][1].length,'\t');break;case DIFF_INSERT:txt.push('+',encodeURI(diffs[x][1]),'\t');break;default:alert('Invalid diff operation in diff_toDelta()')}}return txt.join('').replace(/%20/g,' ')};diff_match_patch.prototype.diff_fromDelta=function(text1,delta){var diffs=[];var pointer=0;var tokens=delta.split(/\t/g);for(var x=0;x<tokens.length;x++){var param=tokens[x].substring(1);switch(tokens[x].charAt(0)){case'-':case'=':var n=parseInt(param,10);if(isNaN(n)||n<0){alert('Invalid number in diff_fromDelta()')}else{var text=text1.substring(pointer,pointer+=n);if(tokens[x].charAt(0)=='='){diffs.push([DIFF_EQUAL,text])}else{diffs.push([DIFF_DELETE,text])}}break;case'+':diffs.push([DIFF_INSERT,decodeURI(param)]);break;default:if(tokens[x]){alert('Invalid diff operation in diff_fromDelta()')}}}if(pointer!=text1.length){alert('Text length mismatch in diff_fromDelta()')}return diffs};diff_match_patch.prototype.match_main=function(text,pattern,loc){loc=Math.max(0,Math.min(loc,text.length-pattern.length));if(text==pattern){return 0}else if(text.length===0){return null}else if(text.substring(loc,loc+pattern.length)==pattern){return loc}else{return this.match_bitap(text,pattern,loc)}};diff_match_patch.prototype.match_bitap=function(text,pattern,loc){if(pattern.length>this.Match_MaxBits){return alert('Pattern too long for this browser.')}var s=this.match_alphabet(pattern);var score_text_length=text.length;score_text_length=Math.max(score_text_length,this.Match_MinLength);score_text_length=Math.min(score_text_length,this.Match_MaxLength);var dmp=this;function match_bitapScore(e,x){var d=Math.abs(loc-x);return(e/pattern.length/dmp.Match_Balance)+(d/score_text_length/(1.0-dmp.Match_Balance))}var score_threshold=this.Match_Threshold;var best_loc=text.indexOf(pattern,loc);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore(0,best_loc),score_threshold)}best_loc=text.lastIndexOf(pattern,loc+pattern.length);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore(0,best_loc),score_threshold)}var matchmask=1<<(pattern.length-1);best_loc=null;var bin_min,bin_mid;var bin_max=Math.max(loc+loc,text.length);var last_rd;for(var d=0;d<pattern.length;d++){var rd=Array(text.length);bin_min=loc;bin_mid=bin_max;while(bin_min<bin_mid){if(match_bitapScore(d,bin_mid)<score_threshold){bin_min=bin_mid}else{bin_max=bin_mid}bin_mid=Math.floor((bin_max-bin_min)/2+bin_min)}bin_max=bin_mid;var start=Math.max(0,loc-(bin_mid-loc)-1);var finish=Math.min(text.length-1,pattern.length+bin_mid);if(text.charAt(finish)==pattern.charAt(pattern.length-1)){rd[finish]=(1<<(d+1))-1}else{rd[finish]=(1<<d)-1}for(var j=finish-1;j>=start;j--){if(d===0){rd[j]=((rd[j+1]<<1)|1)&s[text.charAt(j)]}else{rd[j]=((rd[j+1]<<1)|1)&s[text.charAt(j)]|((last_rd[j+1]<<1)|1)|((last_rd[j]<<1)|1)|last_rd[j+1]}if(rd[j]&matchmask){var score=match_bitapScore(d,j);if(score<=score_threshold){score_threshold=score;best_loc=j;if(j>loc){start=Math.max(0,loc-(j-loc))}else{break}}}}if(match_bitapScore(d+1,loc)>score_threshold){break}last_rd=rd}return best_loc};diff_match_patch.prototype.match_alphabet=function(pattern){var s=Object();for(var i=0;i<pattern.length;i++){s[pattern.charAt(i)]=0}for(var i=0;i<pattern.length;i++){s[pattern.charAt(i)]|=1<<(pattern.length-i-1)}return s};diff_match_patch.prototype.patch_addContext=function(patch,text){var pattern=text.substring(patch.start2,patch.start2+patch.length1);var padding=0;while(text.indexOf(pattern)!=text.lastIndexOf(pattern)&&pattern.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin){padding+=this.Patch_Margin;pattern=text.substring(patch.start2-padding,patch.start2+patch.length1+padding)}padding+=this.Patch_Margin;var prefix=text.substring(patch.start2-padding,patch.start2);if(prefix!==''){patch.diffs.unshift([DIFF_EQUAL,prefix])}var suffix=text.substring(patch.start2+patch.length1,patch.start2+patch.length1+padding);if(suffix!==''){patch.diffs.push([DIFF_EQUAL,suffix])}patch.start1-=prefix.length;patch.start2-=prefix.length;patch.length1+=prefix.length+suffix.length;patch.length2+=prefix.length+suffix.length};diff_match_patch.prototype.patch_make=function(text1,text2,opt_diffs){var diffs;if(typeof opt_diffs!='undefined'){diffs=opt_diffs}else{diffs=this.diff_main(text1,text2,true);if(diffs.length>2){this.diff_cleanupSemantic(diffs);this.diff_cleanupEfficiency(diffs)}}if(diffs.length===0){return[]}var patches=[];var patch=new patch_obj();var char_count1=0;var char_count2=0;var prepatch_text=text1;var postpatch_text=text1;for(var x=0;x<diffs.length;x++){var diff_type=diffs[x][0];var diff_text=diffs[x][1];if(patch.diffs.length===0&&diff_type!==DIFF_EQUAL){patch.start1=char_count1;patch.start2=char_count2}if(diff_type===DIFF_INSERT){patch.diffs.push(diffs[x]);patch.length2+=diff_text.length;postpatch_text=postpatch_text.substring(0,char_count2)+diff_text+postpatch_text.substring(char_count2)}else if(diff_type===DIFF_DELETE){patch.length1+=diff_text.length;patch.diffs.push(diffs[x]);postpatch_text=postpatch_text.substring(0,char_count2)+postpatch_text.substring(char_count2+diff_text.length)}else if(diff_type===DIFF_EQUAL&&diff_text.length<=2*this.Patch_Margin&&patch.diffs.length!==0&&diffs.length!=x+1){patch.diffs.push(diffs[x]);patch.length1+=diff_text.length;patch.length2+=diff_text.length}if(diff_type===DIFF_EQUAL&&diff_text.length>=2*this.Patch_Margin){if(patch.diffs.length!==0){this.patch_addContext(patch,prepatch_text);patches.push(patch);patch=new patch_obj();prepatch_text=postpatch_text}}if(diff_type!==DIFF_INSERT){char_count1+=diff_text.length}if(diff_type!==DIFF_DELETE){char_count2+=diff_text.length}}if(patch.diffs.length!==0){this.patch_addContext(patch,prepatch_text);patches.push(patch)}return patches};diff_match_patch.prototype.patch_apply=function(patches,text){this.patch_splitMax(patches);var results=[];var delta=0;for(var x=0;x<patches.length;x++){var expected_loc=patches[x].start2+delta;var text1=this.diff_text1(patches[x].diffs);var start_loc=this.match_main(text,text1,expected_loc);if(start_loc===null){results.push(false)}else{results.push(true);delta=start_loc-expected_loc;var text2=text.substring(start_loc,start_loc+text1.length);if(text1==text2){text=text.substring(0,start_loc)+this.diff_text2(patches[x].diffs)+text.substring(start_loc+text1.length)}else{var diffs=this.diff_main(text1,text2,false);this.diff_cleanupSemanticLossless(diffs);var index1=0;var index2;for(var y=0;y<patches[x].diffs.length;y++){var mod=patches[x].diffs[y];if(mod[0]!==DIFF_EQUAL){index2=this.diff_xIndex(diffs,index1)}if(mod[0]===DIFF_INSERT){text=text.substring(0,start_loc+index2)+mod[1]+text.substring(start_loc+index2)}else if(mod[0]===DIFF_DELETE){text=text.substring(0,start_loc+index2)+text.substring(start_loc+this.diff_xIndex(diffs,index1+mod[1].length))}if(mod[0]!==DIFF_DELETE){index1+=mod[1].length}}}}}return[text,results]};diff_match_patch.prototype.patch_splitMax=function(patches){for(var x=0;x<patches.length;x++){if(patches[x].length1>this.Match_MaxBits){var bigpatch=patches[x];patches.splice(x,1);var patch_size=this.Match_MaxBits;var start1=bigpatch.start1;var start2=bigpatch.start2;var precontext='';while(bigpatch.diffs.length!==0){var patch=new patch_obj();var empty=true;patch.start1=start1-precontext.length;patch.start2=start2-precontext.length;if(precontext!==''){patch.length1=patch.length2=precontext.length;patch.diffs.push([DIFF_EQUAL,precontext])}while(bigpatch.diffs.length!==0&&patch.length1<patch_size-this.Patch_Margin){var diff_type=bigpatch.diffs[0][0];var diff_text=bigpatch.diffs[0][1];if(diff_type===DIFF_INSERT){patch.length2+=diff_text.length;start2+=diff_text.length;patch.diffs.push(bigpatch.diffs.shift());empty=false}else{diff_text=diff_text.substring(0,patch_size-patch.length1-this.Patch_Margin);patch.length1+=diff_text.length;start1+=diff_text.length;if(diff_type===DIFF_EQUAL){patch.length2+=diff_text.length;start2+=diff_text.length}else{empty=false}patch.diffs.push([diff_type,diff_text]);if(diff_text==bigpatch.diffs[0][1]){bigpatch.diffs.shift()}else{bigpatch.diffs[0][1]=bigpatch.diffs[0][1].substring(diff_text.length)}}}precontext=this.diff_text2(patch.diffs);precontext=precontext.substring(precontext.length-this.Patch_Margin);var postcontext=this.diff_text1(bigpatch.diffs).substring(0,this.Patch_Margin);if(postcontext!==''){patch.length1+=postcontext.length;patch.length2+=postcontext.length;if(patch.diffs.length!==0&&patch.diffs[patch.diffs.length-1][0]===DIFF_EQUAL){patch.diffs[patch.diffs.length-1][1]+=postcontext}else{patch.diffs.push([DIFF_EQUAL,postcontext])}}if(!empty){patches.splice(x++,0,patch)}}}}};diff_match_patch.prototype.patch_toText=function(patches){var text=[];for(var x=0;x<patches.length;x++){text.push(patches[x])}return text.join('')};diff_match_patch.prototype.patch_fromText=function(textline){var patches=[];var text=textline.split('\n');while(text.length!==0){var m=text[0].match(/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/);if(!m){return alert('Invalid patch string:\n'+text[0])}var patch=new patch_obj();patches.push(patch);patch.start1=parseInt(m[1],10);if(m[2]===''){patch.start1--;patch.length1=1}else if(m[2]=='0'){patch.length1=0}else{patch.start1--;patch.length1=parseInt(m[2],10)}patch.start2=parseInt(m[3],10);if(m[4]===''){patch.start2--;patch.length2=1}else if(m[4]=='0'){patch.length2=0}else{patch.start2--;patch.length2=parseInt(m[4],10)}text.shift();while(text.length!==0){var sign=text[0].charAt(0);var line=decodeURIComponent(text[0].substring(1));if(sign=='-'){patch.diffs.push([DIFF_DELETE,line])}else if(sign=='+'){patch.diffs.push([DIFF_INSERT,line])}else if(sign==' '){patch.diffs.push([DIFF_EQUAL,line])}else if(sign=='@'){break}else if(sign===''){}else{return alert('Invalid patch mode: "'+sign+'"\n'+line)}text.shift()}}return patches};function patch_obj(){this.diffs=[];this.start1=null;this.start2=null;this.length1=0;this.length2=0}patch_obj.prototype.toString=function(){var coords1,coords2;if(this.length1===0){coords1=this.start1+',0'}else if(this.length1==1){coords1=this.start1+1}else{coords1=(this.start1+1)+','+this.length1}if(this.length2===0){coords2=this.start2+',0'}else if(this.length2==1){coords2=this.start2+1}else{coords2=(this.start2+1)+','+this.length2}var txt=['@@ -',coords1,' +',coords2,' @@\n'];for(var x=0;x<this.diffs.length;x++){switch(this.diffs[x][0]){case DIFF_DELETE:txt.push('-');break;case DIFF_EQUAL:txt.push(' ');break;case DIFF_INSERT:txt.push('+');break;default:alert('Invalid diff operation in patch_obj.toString()')}txt.push(encodeURI(this.diffs[x][1]),'\n')}return txt.join('').replace(/%20/g,' ')};
@@ -0,0 +1,111 @@
1
+
2
+ describe('util.PathUtils#basenameの動作確認', {
3
+ '"aaa/bbb.txt" → "bbb.txt" ': function() {
4
+ value_of(util.PathUtils.basename("aaa/bbb.txt")).should_be("bbb.txt");
5
+ },
6
+ '"/aaa/ccc/bbb" → "bbb" ': function() {
7
+ value_of(util.PathUtils.basename("/aaa/ccc/bbb")).should_be("bbb");
8
+ },
9
+ '"aaa/日本語" → "日本語" ': function() {
10
+ value_of(util.PathUtils.basename("aaa/日本語")).should_be("日本語");
11
+ },
12
+ '"日本語" (スラッシュを含まない) → "日本語" ': function() {
13
+ value_of(util.PathUtils.basename("日本語")).should_be("日本語");
14
+ },
15
+ '"日本語/" (スラッシュが末尾) → "" ': function() {
16
+ value_of(util.PathUtils.basename("日本語/")).should_be("");
17
+ },
18
+ '"/" (スラッシュのみ) → "" ': function() {
19
+ value_of(util.PathUtils.basename("/")).should_be("");
20
+ },
21
+ '"" (空文字列) → "" ': function() {
22
+ value_of(util.PathUtils.basename("")).should_be("");
23
+ },
24
+ 'null → "" ': function() {
25
+ value_of(util.PathUtils.basename(null)).should_be("");
26
+ },
27
+ 'undefined → "" ': function() {
28
+ value_of(util.PathUtils.basename(undefined)).should_be("");
29
+ }
30
+ });
31
+
32
+ describe('util.PathUtils#dirnameの動作確認', {
33
+ '"aaa/bbb.txt" → "aaa" ': function() {
34
+ value_of(util.PathUtils.dirname("aaa/bbb.txt")).should_be("aaa");
35
+ },
36
+ '"/aaa/ccc/bbb" → "/aaa/ccc" ': function() {
37
+ value_of(util.PathUtils.dirname("/aaa/ccc/bbb")).should_be("/aaa/ccc");
38
+ },
39
+ '"/a/日本語/日本語" → "/a/日本語" ': function() {
40
+ value_of(util.PathUtils.dirname("/a/日本語/日本語")).should_be("/a/日本語");
41
+ },
42
+ '"日本語" (スラッシュを含まない) → "" ': function() {
43
+ value_of(util.PathUtils.dirname("日本語")).should_be("");
44
+ },
45
+ '"日本語/" (スラッシュが末尾) → "" ': function() {
46
+ value_of(util.PathUtils.dirname("日本語/")).should_be("日本語");
47
+ },
48
+ '"/" (スラッシュのみ) → "" ': function() {
49
+ value_of(util.PathUtils.dirname("/")).should_be("");
50
+ },
51
+ '"" (空文字列) → "" ': function() {
52
+ value_of(util.PathUtils.dirname("")).should_be("");
53
+ },
54
+ 'null → "" ': function() {
55
+ value_of(util.PathUtils.dirname(null)).should_be("");
56
+ },
57
+ 'undefined → "" ': function() {
58
+ value_of(util.PathUtils.dirname(undefined)).should_be("");
59
+ }
60
+ });
61
+
62
+ describe('util.PathUtils#isChildの動作確認', {
63
+ 'path:"aaa/bbb/ccc", dir:"aaa/bbb", → true ': function() {
64
+ value_of(util.PathUtils.isChild("aaa/bbb/ccc", "aaa/bbb")).should_be(true);
65
+ },
66
+ 'path:"aaa/bbb/ccc", dir:"aaa", → true ': function() {
67
+ value_of(util.PathUtils.isChild("aaa/bbb/ccc", "aaa")).should_be(true);
68
+ },
69
+ 'path:"aaa/bbb/ccc", dir:"aaa/ccc", → false ': function() {
70
+ value_of(util.PathUtils.isChild("aaa/bbb/ccc", "aaa/ccc")).should_be(false);
71
+ },
72
+ 'path:"aaa/bbb/ccc", dir:"aaa/bbbb", → false': function() {
73
+ value_of(util.PathUtils.isChild("aaa/bbb/ccc", "aaa/bbbb")).should_be(false);
74
+ },
75
+ 'path:"aaa/bbb/ccc", dir:"aaa/bb", → false': function() {
76
+ value_of(util.PathUtils.isChild("aaa/bbb/ccc", "aaa/bb")).should_be(false);
77
+ },
78
+ 'path:"日本語/ccc", dir:"日本語", → true': function() {
79
+ value_of(util.PathUtils.isChild("日本語/ccc", "日本語")).should_be(true);
80
+ },
81
+ 'path:"/日本語/ccc", dir:"", → true': function() {
82
+ value_of(util.PathUtils.isChild("/日本語/ccc", "")).should_be(true);
83
+ },
84
+ 'path:"", dir:"", → true': function() {
85
+ value_of(util.PathUtils.isChild("", "")).should_be(false);
86
+ }
87
+ });
88
+
89
+ describe('util.PathUtils#normarizeの動作確認', {
90
+ '基本のパターン': function() {
91
+ value_of(util.PathUtils.normarize([
92
+ "aaa/bbb",
93
+ "aaa",
94
+ "aa",
95
+ "aa/xx",
96
+ "aa/cc/dd",
97
+ "aa/cc",
98
+ "bb/dd/ss",
99
+ "bb/dd",
100
+ "cc/xx"
101
+ ])).should_be([
102
+ "aa",
103
+ "aaa",
104
+ "bb/dd",
105
+ "cc/xx"
106
+ ]);
107
+ },
108
+ '空の配列': function() {
109
+ value_of(util.PathUtils.normarize([])).should_be([]);
110
+ }
111
+ });
@@ -4,26 +4,65 @@ require "jiji/models"
4
4
  require 'jiji/util/util'
5
5
  require 'jiji/operator'
6
6
  require 'jiji/output'
7
+ require 'jiji/util/include_proxy'
7
8
 
8
9
  module JIJI
9
10
 
10
- # エージェントを示すマーカーモジュール
11
+ #===エージェントを示すマーカーモジュール
12
+ #JIJIではこのモジュールをincludeしたクラスがエージェントとして認識されます。
13
+ #
11
14
  module Agent
12
- # プロパティ設定後に呼び出される。
15
+
16
+ module Shared #:nodoc:
17
+ @@deleates = {}
18
+ def self.const_missing(id)
19
+ super unless @@deleates
20
+ result = nil
21
+ @@deleates.each_pair{|k,v|
22
+ if v.const_defined?(id)
23
+ result = v.const_get(id)
24
+ break
25
+ end
26
+ }
27
+ result ? result : super
28
+ end
29
+ def self.method_missing(name,*args, &block)
30
+ super unless @@deleates
31
+ target = nil
32
+ @@deleates.each_pair{|k,v|
33
+ if v.respond_to?(name)
34
+ target = v
35
+ break
36
+ end
37
+ }
38
+ target ? target.send( name, *args, &block ) : super
39
+ end
40
+ def self._delegates
41
+ @@deleates
42
+ end
43
+ end
44
+
45
+ #====エージェントの登録後に1度だけ呼び出される関数。
46
+ #必要に応じてオーバーライドしてください。コンストラクタと違いこのメソッドではoperatorやoutput,loggerが使用可能です。
13
47
  def init( )
14
48
  end
15
- # 次のレートを受け取る
49
+ #====レート情報が通知されるメソッドです。
50
+ #エージェントが動作している間順次呼び出されます。
51
+ #このメソッドをオーバーライドして、シグナルの計算や取り引きを行うロジックを実装してください
52
+ #rates:: JIJI::Rates
16
53
  def next_rates( rates )
17
54
  end
18
- # 設定可能なプロパティの一覧を返す
55
+ #====設定可能なプロパティの一覧を返します。
56
+ #必要に応じてオーバーライドしてください。
57
+ #戻り値:: JIJI::Agent::Propertyの配列
19
58
  def property_infos
20
59
  []
21
60
  end
22
- # 設定されたプロパティを取得する
61
+ #====設定されたプロパティを取得します。
23
62
  def properties
24
63
  @properties
25
64
  end
26
- # プロパティを設定する
65
+ #====プロパティを設定します。
27
66
  def properties=( properties )
28
67
  @properties = properties
29
68
  properties.each_pair {|k,v|
@@ -31,7 +70,8 @@ module JIJI
31
70
  }
32
71
  end
33
72
 
34
- # エージェントの説明を返す
73
+ #====エージェントの説明を返します。
74
+ #必要に応じてオーバーライドしてください。
35
75
  def description
36
76
  ""
37
77
  end
@@ -43,28 +83,41 @@ module JIJI
43
83
  # データの出力先
44
84
  attr :output, true
45
85
 
46
- # エージェントのプロパティ
86
+ #===エージェントのプロパティ
47
87
  class Property
48
88
  include JIJI::Util::Model
49
89
  include JIJI::Util::JsonSupport
90
+ #====コンストラクタ
91
+ #id:: プロパティID
92
+ #name:: UIでの表示名
93
+ #default_value:: プロパティの初期値
94
+ #type:: 種類
50
95
  def initialize( id, name, default_value=nil, type=:string )
51
96
  @id = id
52
97
  @name = name
53
98
  @default = default_value
54
99
  @type = type
55
100
  end
101
+ #プロパティID。
102
+ #JIJI::Agent#properties=(props)で渡されるハッシュのキーになります。設定必須です。
56
103
  attr :id, true
57
- attr :name, true # UIでの表示用の名前
58
- attr :default, true # 初期値
104
+ # UIでの表示名。設定必須です。
105
+ attr :name, true
106
+ # プロパティの初期値。
107
+ attr :default, true
108
+ # 種類。:string or :numberが指定可能。指定しない場合、:stringが指定されたものとみなされます。
59
109
  attr :type, true
60
110
  end
61
111
 
62
112
  end
63
113
 
64
-
65
- # 一定期間ごとに通知を受け取るエージェントの基底クラス。
114
+ #===一定期間ごとに通知を受け取るエージェントの基底クラス。
66
115
  class PeriodicallyAgent
67
116
  include JIJI::Agent
117
+ include_proxy JIJI::Agent::Shared
118
+
119
+ #====コンストラクタ
120
+ #period:: レートの通知を受け取る間隔(分)の初期値
68
121
  def initialize( period=10 )
69
122
  @period = period
70
123
  @start = nil
@@ -85,6 +138,10 @@ module JIJI
85
138
  def property_infos
86
139
  super() + [Property.new(:period, "レートの通知を受け取る間隔(分)", 10, :number)]
87
140
  end
141
+ #====レート情報が通知されるメソッドです。
142
+ #エージェントが動作している間順次呼び出されます。
143
+ #このメソッドをオーバーライドして、シグナルの計算や取り引きを行うロジックを実装してください
144
+ #rates:: JIJI::PeriodicallyRates
88
145
  def next_period_rates( rates )
89
146
  end
90
147
  end
@@ -15,12 +15,17 @@ module JIJI
15
15
 
16
16
  include JIJI::AgentUtil
17
17
  include Enumerable
18
- State = Struct.new( :agent, :output, :active )
19
-
20
- def initialize( id, registry, logger, failsafe=true )
21
- @id = id
18
+ State = Struct.new( :agent, :output, :operator, :active )
19
+
20
+ #コンストラクタ
21
+ #process_id:: プロセスID
22
+ #agent_registry:: エージェントレジストリ
23
+ #logger:: ロガー
24
+ #failsafe:: レートを通知した際にエージェントで発生したエラーを無視するかどうか?
25
+ def initialize( process_id, agent_registry, logger, failsafe=true )
26
+ @process_id = process_id
22
27
  @agents = {}
23
- @agent_registry = registry
28
+ @agent_registry = agent_registry
24
29
  @logger = logger
25
30
  # エージェントでエラーが発生した場合にエラーを無視し実行を継続するか
26
31
  # true の場合、ログ出力後エラーを握って処理を継続(RMTはこちらで動作する)
@@ -29,19 +34,20 @@ module JIJI
29
34
  end
30
35
 
31
36
  # エージェントを追加する
32
- def add( id, agent, name="" )
33
- if @agents.key? id
34
- raise UserError.new( JIJI::ERROR_ALREADY_EXIST, "agent is already exist. id=#{id}")
37
+ def add( agent_id, agent, agent_name="" )
38
+ if @agents.key? agent_id
39
+ raise UserError.new( JIJI::ERROR_ALREADY_EXIST, "agent is already exist. id=#{agent_id}")
35
40
  end
36
- output = @registry.output( @id, id )
37
- op = AgentOperator.new( @operator, name )
41
+ output = @output_manager.create( @process_id, agent_id )
42
+ output.agent_name = agent_name
43
+ op = AgentOperator.new( @operator, agent_name )
38
44
  safe( conf.get( [:agent,:safe_level], 4) ){
39
45
  agent.operator = op
40
46
  agent.logger = @logger
41
47
  agent.output = output
42
48
  agent.init
43
49
  }
44
- @agents[id] = State.new( agent, output, true )
50
+ @agents[agent_id] = State.new( agent, output, op, true )
45
51
  end
46
52
 
47
53
  # エージェントを破棄する
@@ -126,7 +132,7 @@ module JIJI
126
132
  attr :trade_result_dao, true
127
133
  attr :operator, true
128
134
  attr :conf, true
129
- attr :registry, true
135
+ attr :output_manager, true
130
136
  end
131
137
 
132
138
  end
@@ -4,40 +4,10 @@ require 'jiji/agent/agent'
4
4
  require 'jiji/agent/util'
5
5
  require 'jiji/util/file_lock'
6
6
  require 'set'
7
+ require 'logger'
7
8
 
8
9
  module JIJI
9
-
10
- module Agent
11
- module Shared
12
- @@deleates = {}
13
- def self.const_missing(id)
14
- super unless @@deleates
15
- result = nil
16
- @@deleates.each_pair{|k,v|
17
- if v.const_defined?(id)
18
- result = v.const_get(id)
19
- break
20
- end
21
- }
22
- result ? result : super
23
- end
24
- def self.method_missing(name,*args, &block)
25
- super unless @@deleates
26
- target = nil
27
- @@deleates.each_pair{|k,v|
28
- if v.respond_to?(name)
29
- target = v
30
- break
31
- end
32
- }
33
- target ? target.send( name, *args, &block ) : super
34
- end
35
- def self._delegates
36
- @@deleates
37
- end
38
- end
39
- end
40
-
10
+
41
11
  #==エージェントレジストリ
42
12
  class AgentRegistry
43
13
 
@@ -46,10 +16,7 @@ module JIJI
46
16
 
47
17
  def initialize( agent_dir, shared_lib_dir )
48
18
  @agent_dir = agent_dir
49
- FileUtils.mkdir_p @agent_dir
50
19
  @shared_lib_dir = shared_lib_dir
51
- FileUtils.mkdir_p @shared_lib_dir
52
-
53
20
  @agents = {}
54
21
  end
55
22
 
@@ -78,7 +45,7 @@ module JIJI
78
45
  raise UserError.new( JIJI::ERROR_NOT_FOUND,
79
46
  "agent class not found. name=#{name}")
80
47
  end
81
- m = @agents[$2]
48
+ m = @agents["agents/#{$2}"]
82
49
  unless m
83
50
  raise UserError.new( JIJI::ERROR_NOT_FOUND,
84
51
  "agent class not found. name=#{name}")
@@ -126,118 +93,64 @@ module JIJI
126
93
  }
127
94
  end
128
95
 
129
- # ファイル名の一覧を得る。
130
- def files( type=:agent )
131
- lock(type) {
132
- Dir.glob( "#{dir(type)}/*.rb" ).map {|item|
133
- { "name" =>File.basename(item),
134
- "update"=>File.mtime(item).to_i }
135
- }.sort_by {|item| item["name"] }
136
- }
137
- end
138
-
139
- # エージェントファイルの本文を取得する。
140
- def get_file(file, type=:agent )
141
- lock(type) {
142
- file = "#{dir(type)}/#{file}"
143
- unless File.exist? file
144
- raise UserError.new( JIJI::ERROR_NOT_FOUND,
145
- "#{type} file not found. file_name=#{file}}")
146
- end
147
- IO.read(file)
148
- }
149
- end
150
-
151
96
  # エージェント置き場から、エージェントをロードする。
97
+ # 起動時に一度だけ呼ばれる。
152
98
  def load_all
153
- lock(:shared_lib) {
154
- Dir.glob( "#{@shared_lib_dir}/*.rb" ) {|shared_lib_file|
155
- inner_load( shared_lib_file, :shared_lib )
156
- }
157
- }
158
- lock(:agent) {
159
- Dir.glob( "#{@agent_dir}/*.rb" ) {|agent_file|
160
- inner_load( agent_file, :agent )
99
+ [@agent_dir,@shared_lib_dir].each {|d|
100
+ @file_dao.list( d, true ).each {|item|
101
+ next if item[:type] == :directory
102
+ begin
103
+ inner_load( item[:path] )
104
+ rescue Exception
105
+ # ログ出力のみ行い、例外は握る。
106
+ server_logger.error( $! )
107
+ end
161
108
  }
162
109
  }
163
110
  end
164
111
 
165
112
  # 特定のファイルをロードする。
166
113
  def load(file)
167
- file = "#{@agent_dir}/#{file}"
168
- unless File.exist? file
169
- raise UserError.new( JIJI::ERROR_NOT_FOUND,
170
- "agent file not found. file_name=#{file}}")
171
- end
172
- lock(:agent) { inner_load( file ) }
114
+ inner_load( file )
173
115
  end
174
116
 
175
- # ファイルを追加/更新する。
176
- def add_file( file_name, body, type=:agent )
177
- lock(type) {
178
- file = "#{dir(type)}/#{file_name}"
179
- File.open( file, "w" ) {|f|
180
- f.puts body
181
- }
182
- inner_load( file, type )
183
- }
184
- end
185
-
186
- # ファイルを破棄する
187
- def remove_file( file_name, type=:agent )
188
- lock(type) {
189
- file = "#{dir(type)}/#{file_name}"
190
- unless File.exist? file
191
- raise UserError.new( JIJI::ERROR_NOT_FOUND,
192
- "#{type} file not found. file_name=#{file_name}")
193
- end
194
- FileUtils.rm_rf file
195
- @agents.delete file_name if type==:agent
196
- }
117
+ # 特定のファイルをアンロードする。
118
+ def unload(file)
119
+ if file =~ /^#{@agent_dir}\/.*/
120
+ @agents.delete file
121
+ else
122
+ JIJI::Agent::Shared._delegates.delete file
123
+ end
197
124
  end
198
125
 
199
126
  attr :conf, true
200
-
127
+ attr :file_dao, true
128
+ attr :server_logger, true
201
129
  private
202
130
 
203
- # 種別に対応するディレクトリ名を得る。
204
- def dir( type )
205
- return type == :agent ? @agent_dir : @shared_lib_dir
206
- end
207
-
208
- def inner_load( file, type=:agent )
209
- error = nil
210
- body = IO.read(file).taint
131
+ def inner_load( file )
132
+ body = @file_dao.get(file).taint
211
133
  m = Module.new.taint
212
- if type == :agent
213
- @agents[ File.basename(file) ] = m
134
+ if file =~ /^#{@agent_dir}\/.*/
135
+ @agents[ file ] = m
136
+ elsif file =~ /^#{@shared_lib_dir}\/.*/
137
+ JIJI::Agent::Shared._delegates[ file ] = m
214
138
  else
215
- JIJI::Agent::Shared._delegates[ File.basename(file) ] = m
139
+ return # agent,shared_lib配下のファイル以外は読み込まない。
216
140
  end
217
141
  safe( conf.get( [:agent,:safe_level], 4) ){
218
- begin
219
- m.module_eval( body, file, 1 )
220
- rescue Exception => e
221
- # エラーになっても読み込みは継続。
222
- # 戻り値としてエラーの情報を返す
223
- error = e.to_s
224
- end
142
+ m.module_eval( body, file, 1 )
225
143
  }
226
- return error ? error : :success
227
144
  end
228
145
 
229
- def lock( type=:agent )
230
- DirLock.new( dir(type) ).writelock {
231
- yield if block_given?
232
- }
233
- end
234
146
  def find_agent( file, m, checked, &block )
235
147
  return if checked.include? m
236
148
  checked << m
237
149
  m.constants.each {|name|
238
150
  cl = m.const_get name
239
- begin
240
- block.call( "#{get_name(cl.name)}@#{file}" ) if cl.kind_of?(Class) && cl < JIJI::Agent
151
+ agent_file = file.sub( /^#{@agent_dir}\/?/, "" )
152
+ begin
153
+ block.call( "#{get_name(cl.name)}@#{agent_file}" ) if cl.kind_of?(Class) && cl < JIJI::Agent
241
154
  rescue Exception
242
155
  end
243
156
  find_agent( file, cl, checked, &block ) if cl.kind_of?(Module)
@@ -246,6 +159,7 @@ module JIJI
246
159
  def get_name( name )
247
160
  name.split("::", 2)[1]
248
161
  end
162
+
249
163
  end
250
164
 
251
165
  end
@@ -111,12 +111,7 @@ module JIJI
111
111
  @end_mutex.synchronize { @alive = false }
112
112
 
113
113
  # リスナに通知
114
- @listeners.each {|l|
115
- begin
116
- l.on_finished( @state, Time.at(@now) ) if l.respond_to? :on_finished
117
- rescue Exception
118
- end
119
- }
114
+ callback( :on_finished, @state, Time.at(@now || Time.now) )
120
115
  }
121
116
  end
122
117
  end
@@ -136,6 +131,14 @@ module JIJI
136
131
  }
137
132
  end
138
133
  end
134
+ # リスナにイベントを通知する
135
+ def callback( method, *args )
136
+ @listeners.each {|l|
137
+ JIJI::Util.log_if_error( @logger ) {
138
+ l.send(method, *args ) if l.respond_to? method
139
+ }
140
+ }
141
+ end
139
142
  end
140
143
 
141
144
  #
@@ -156,12 +159,17 @@ module JIJI
156
159
  end
157
160
  def collect
158
161
  JIJI::Util.log_if_error_and_throw( @logger ) {
162
+ callback( :on_progress_changed, @progress )
159
163
  begin
160
164
  pairs = @dao.list_pairs
161
165
  if pairs.length > 0
162
166
  @start_date = @start_date || Time.at( @dao.dao(pairs[0]).first_time(:raw) )
163
167
  @end_date = @end_date || Time.at( @dao.dao(pairs[0]).last_time(:raw) )
168
+ else
169
+ @start_date = @start_date || 0
170
+ @end_date = @end_date || Time.now
164
171
  end
172
+ @now = @start_date.to_i
165
173
  @dao.each_all_pair_rates(:raw, @start_date, @end_date ) {|rates|
166
174
  each_rate(rates)
167
175
  # キャンセルチェック
@@ -174,6 +182,7 @@ module JIJI
174
182
  @state_mutex.synchronize {
175
183
  @progress = 100
176
184
  }
185
+ callback( :on_progress_changed, @progress )
177
186
  end
178
187
  }
179
188
  end
@@ -207,6 +216,7 @@ module JIJI
207
216
  all = @end_date.to_i - @start_date.to_i
208
217
  @progress = ( current*100 / all ).to_i
209
218
  }
219
+ callback( :on_progress_changed, @progress )
210
220
  end
211
221
  end
212
222
  end