Commit 276f98adb32b7fc0e138882a4d8f641f93529257
1 parent
4fbcce8d
update...
Showing
11 changed files
with
84 additions
and
39 deletions
src/main/java/com/bsth/controller/XmlInfoPublishController.java
| @@ -135,7 +135,7 @@ public class XmlInfoPublishController { | @@ -135,7 +135,7 @@ public class XmlInfoPublishController { | ||
| 135 | StringBuilder sb = new StringBuilder(); | 135 | StringBuilder sb = new StringBuilder(); |
| 136 | 136 | ||
| 137 | try { | 137 | try { |
| 138 | - | 138 | + long ct = System.currentTimeMillis(); |
| 139 | int upDown = Integer.parseInt(direction); | 139 | int upDown = Integer.parseInt(direction); |
| 140 | List<GpsEntity> list = GpsCacheData.findList(lineid, upDown); | 140 | List<GpsEntity> list = GpsCacheData.findList(lineid, upDown); |
| 141 | 141 | ||
| @@ -152,6 +152,11 @@ public class XmlInfoPublishController { | @@ -152,6 +152,11 @@ public class XmlInfoPublishController { | ||
| 152 | 152 | ||
| 153 | int serialNo = es.getSerialNo(); | 153 | int serialNo = es.getSerialNo(); |
| 154 | for (GpsEntity gps : list) { | 154 | for (GpsEntity gps : list) { |
| 155 | + if (ct - gps.getTimestamp() > 1000 * 60 * 10) | ||
| 156 | + continue;//掉线超过10分钟,不发布 | ||
| 157 | + | ||
| 158 | + //短时间掉线,平滑过渡 | ||
| 159 | + gps.smoothTransition(ct); | ||
| 155 | 160 | ||
| 156 | s = GeoCacheData.findByCode(gps); | 161 | s = GeoCacheData.findByCode(gps); |
| 157 | if (null == s || s.getSerialNo() > serialNo) | 162 | if (null == s || s.getSerialNo() > serialNo) |
| @@ -206,8 +211,10 @@ public class XmlInfoPublishController { | @@ -206,8 +211,10 @@ public class XmlInfoPublishController { | ||
| 206 | sb.append("<car>"); | 211 | sb.append("<car>"); |
| 207 | sb.append("<terminal>" + BasicCacheData.device2plateMap.get(v.getDeviceId()) + "</terminal>"); | 212 | sb.append("<terminal>" + BasicCacheData.device2plateMap.get(v.getDeviceId()) + "</terminal>"); |
| 208 | 213 | ||
| 214 | + //当前站 缓冲区内 的车(进站时间不超过 40秒的,可以发布) | ||
| 209 | if (v.getStationCode().equals(stopid) | 215 | if (v.getStationCode().equals(stopid) |
| 210 | - && v.getInOut() == 1) {//当前站 缓冲区内 的车 | 216 | + && v.getInOut() == 1 |
| 217 | + && (null != v.getInStationTime() && ct - v.getInStationTime() < 40)) { | ||
| 211 | sb.append("<stopdis>0</stopdis>"); | 218 | sb.append("<stopdis>0</stopdis>"); |
| 212 | sb.append("<distance>0</distance>"); | 219 | sb.append("<distance>0</distance>"); |
| 213 | sb.append("<time>0</time>"); | 220 | sb.append("<time>0</time>"); |
src/main/java/com/bsth/data/gps/GpsCacheData.java
| @@ -111,9 +111,15 @@ public class GpsCacheData { | @@ -111,9 +111,15 @@ public class GpsCacheData { | ||
| 111 | public static Map<String, Object> find(String lineCode, int upDown) { | 111 | public static Map<String, Object> find(String lineCode, int upDown) { |
| 112 | List<String> ds = lineRealMap.get(lineCode + "_" + upDown); | 112 | List<String> ds = lineRealMap.get(lineCode + "_" + upDown); |
| 113 | 113 | ||
| 114 | + long t = System.currentTimeMillis(); | ||
| 114 | List<GpsEntity> list = new ArrayList<>(ds.size()); | 115 | List<GpsEntity> list = new ArrayList<>(ds.size()); |
| 116 | + GpsEntity gps; | ||
| 115 | for (String d : ds) { | 117 | for (String d : ds) { |
| 116 | - list.add(findOne(d)); | 118 | + gps = findOne(d); |
| 119 | + if(gps.getNbbm().equals("W1F-052")) | ||
| 120 | + System.out.println("aaaa"); | ||
| 121 | + gps.smoothTransition(t); | ||
| 122 | + list.add(gps); | ||
| 117 | } | 123 | } |
| 118 | 124 | ||
| 119 | Map<String, Object> rs = new HashMap<>(); | 125 | Map<String, Object> rs = new HashMap<>(); |
src/main/java/com/bsth/data/gps/process/DataMainProcessor.java
| @@ -105,6 +105,8 @@ public class DataMainProcessor { | @@ -105,6 +105,8 @@ public class DataMainProcessor { | ||
| 105 | 105 | ||
| 106 | for (GpsEntity gps : list) { | 106 | for (GpsEntity gps : list) { |
| 107 | gps.setNbbm(BasicCacheData.device2nbbmMap.get(gps.getDeviceId())); | 107 | gps.setNbbm(BasicCacheData.device2nbbmMap.get(gps.getDeviceId())); |
| 108 | + if (null == gps.getNbbm()) | ||
| 109 | + continue; | ||
| 108 | data.put(gps.getDeviceId(), gps); | 110 | data.put(gps.getDeviceId(), gps); |
| 109 | } | 111 | } |
| 110 | 112 |
src/main/java/com/bsth/data/gps/process/chains/ForecastProcess.java
| @@ -20,7 +20,7 @@ public class ForecastProcess { | @@ -20,7 +20,7 @@ public class ForecastProcess { | ||
| 20 | private final static int OUT_BOUNDS = 80; | 20 | private final static int OUT_BOUNDS = 80; |
| 21 | 21 | ||
| 22 | public void process(GpsEntity gps) { | 22 | public void process(GpsEntity gps) { |
| 23 | - //获取10分钟内的点位,如果不够,5分钟也行 | 23 | + //获取6分钟内的点位,如果不够,4分钟也行 |
| 24 | List<GpsEntity> list = GpsCacheData.prev(gps.getDeviceId(), 60 * 10, 60 * 5); | 24 | List<GpsEntity> list = GpsCacheData.prev(gps.getDeviceId(), 60 * 10, 60 * 5); |
| 25 | list.add(gps); | 25 | list.add(gps); |
| 26 | 26 | ||
| @@ -28,7 +28,7 @@ public class ForecastProcess { | @@ -28,7 +28,7 @@ public class ForecastProcess { | ||
| 28 | if (isValidSignal(list)) { | 28 | if (isValidSignal(list)) { |
| 29 | GpsEntity first = list.get(0); | 29 | GpsEntity first = list.get(0); |
| 30 | double sumDist = GeoUtils.getDistance(first, gps);//行驶距离 | 30 | double sumDist = GeoUtils.getDistance(first, gps);//行驶距离 |
| 31 | - double seconds = (gps.getTimestamp() - first.getTimestamp()) / 1000;//耗时 | 31 | + double seconds = (gps.getTimestamp() - first.getTimestamp()) / 1000 - 30;//耗时 |
| 32 | double avgSpeed = sumDist / seconds;//均速 | 32 | double avgSpeed = sumDist / seconds;//均速 |
| 33 | gps.setSeconds((int) (gps.getDistance() / avgSpeed));//到下一站的时间 | 33 | gps.setSeconds((int) (gps.getDistance() / avgSpeed));//到下一站的时间 |
| 34 | } else { | 34 | } else { |
| @@ -45,22 +45,6 @@ public class ForecastProcess { | @@ -45,22 +45,6 @@ public class ForecastProcess { | ||
| 45 | } | 45 | } |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | -/* private Integer[] getJHTimeArray(GpsEntity gps) { | ||
| 49 | - List<StationRoute> srs = GeoCacheData.find(gps.getLineId(), gps.getUpDown()); | ||
| 50 | - String sCode = gps.getStationCode() | ||
| 51 | - , eCode = srs.get(srs.size() - 1).getStationCode(); | ||
| 52 | - | ||
| 53 | - ScheduleRealInfo sch = gps.getSch(); | ||
| 54 | - if (null != sch | ||
| 55 | - && null != sch.getQdzCode() | ||
| 56 | - && null != sch.getZdzCode()) { | ||
| 57 | - | ||
| 58 | - eCode = sch.getZdzCode(); | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - return HistoryConsumeTimeDataHandler.findConsumeArray(gps.getLineId(), gps.getUpDown(), sCode, eCode); | ||
| 62 | - }*/ | ||
| 63 | - | ||
| 64 | private boolean isValidSignal(List<GpsEntity> list) { | 48 | private boolean isValidSignal(List<GpsEntity> list) { |
| 65 | if (list.size() <= 1) | 49 | if (list.size() <= 1) |
| 66 | return false; | 50 | return false; |
src/main/java/com/bsth/data/gps/process/chains/InOutStationProcess.java
| @@ -80,9 +80,12 @@ public class InOutStationProcess { | @@ -80,9 +80,12 @@ public class InOutStationProcess { | ||
| 80 | inStation(gps, prev); | 80 | inStation(gps, prev); |
| 81 | 81 | ||
| 82 | //进站2 从站内到另一个站内 | 82 | //进站2 从站内到另一个站内 |
| 83 | - if (prev.getInOut() == 1 && gps.getInOut() == 1 | ||
| 84 | - && !prev.getStationCode().equals(gps.getStationCode())) | ||
| 85 | - inStation(gps, prev); | 83 | + if (prev.getInOut() == 1 && gps.getInOut() == 1) { |
| 84 | + if (!prev.getStationCode().equals(gps.getStationCode())) | ||
| 85 | + inStation(gps, prev); | ||
| 86 | + else | ||
| 87 | + gps.setInStationTime(prev.getInStationTime()); | ||
| 88 | + } | ||
| 86 | 89 | ||
| 87 | //进站3 从场内到站内 | 90 | //进站3 从场内到站内 |
| 88 | if (prev.getInOut() == 2 && gps.getInOut() == 1) | 91 | if (prev.getInOut() == 2 && gps.getInOut() == 1) |
| @@ -167,6 +170,7 @@ public class InOutStationProcess { | @@ -167,6 +170,7 @@ public class InOutStationProcess { | ||
| 167 | if (null == s) | 170 | if (null == s) |
| 168 | return; | 171 | return; |
| 169 | 172 | ||
| 173 | + gps.setInStationTime(gps.getTimestamp());//进站时间 | ||
| 170 | //存一份站点间耗时数据 | 174 | //存一份站点间耗时数据 |
| 171 | historyConsumeTimeData.in(gps, prev); | 175 | historyConsumeTimeData.in(gps, prev); |
| 172 | 176 |
src/main/java/com/bsth/data/history/HistoryConsumeTimeDataHandler.java
| @@ -56,6 +56,12 @@ public class HistoryConsumeTimeDataHandler { | @@ -56,6 +56,12 @@ public class HistoryConsumeTimeDataHandler { | ||
| 56 | private final static int EVENIGN_PEAK_E = 190000; | 56 | private final static int EVENIGN_PEAK_E = 190000; |
| 57 | 57 | ||
| 58 | 58 | ||
| 59 | + //稀疏进站距离时,给的默认速度 | ||
| 60 | + private final static int IN_STATION_SPEED = 15; | ||
| 61 | + | ||
| 62 | + //按实时路段距离换算时间时,给的默认速度 | ||
| 63 | + private final static int DEFAULT_SPEED = 18; | ||
| 64 | + | ||
| 59 | /** | 65 | /** |
| 60 | * K : lineCode_upDown | 66 | * K : lineCode_upDown |
| 61 | */ | 67 | */ |
| @@ -106,7 +112,7 @@ public class HistoryConsumeTimeDataHandler { | @@ -106,7 +112,7 @@ public class HistoryConsumeTimeDataHandler { | ||
| 106 | sum += ns[i]; | 112 | sum += ns[i]; |
| 107 | } | 113 | } |
| 108 | 114 | ||
| 109 | - return sum + gps.getSeconds(); | 115 | + return sum + (null == gps.getSeconds2() ? gps.getSeconds() : gps.getSeconds2()); |
| 110 | } | 116 | } |
| 111 | 117 | ||
| 112 | public void start() { | 118 | public void start() { |
| @@ -223,7 +229,7 @@ public class HistoryConsumeTimeDataHandler { | @@ -223,7 +229,7 @@ public class HistoryConsumeTimeDataHandler { | ||
| 223 | dt.minusDays(7);//减7天 | 229 | dt.minusDays(7);//减7天 |
| 224 | String rq = dt.toString("yyyyMMdd "); | 230 | String rq = dt.toString("yyyyMMdd "); |
| 225 | 231 | ||
| 226 | - rq = "20180620"; | 232 | + rq = "20180627"; |
| 227 | String sql = "select * from bsth_h_consume_time where rq=" + rq; | 233 | String sql = "select * from bsth_h_consume_time where rq=" + rq; |
| 228 | JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_InfoPublish.getDataSource()); | 234 | JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_InfoPublish.getDataSource()); |
| 229 | List<StationConsumeTime> list = | 235 | List<StationConsumeTime> list = |
| @@ -317,7 +323,7 @@ public class HistoryConsumeTimeDataHandler { | @@ -317,7 +323,7 @@ public class HistoryConsumeTimeDataHandler { | ||
| 317 | s = GeoCacheData.findByCode(lineCode, upDown, code); | 323 | s = GeoCacheData.findByCode(lineCode, upDown, code); |
| 318 | 324 | ||
| 319 | if (null != s) | 325 | if (null != s) |
| 320 | - times[i] = (int) s.getLength() / 12; | 326 | + times[i] = (int) s.getLength() / DEFAULT_SPEED; |
| 321 | else | 327 | else |
| 322 | times[i] = 55; | 328 | times[i] = 55; |
| 323 | } | 329 | } |
| @@ -341,7 +347,7 @@ public class HistoryConsumeTimeDataHandler { | @@ -341,7 +347,7 @@ public class HistoryConsumeTimeDataHandler { | ||
| 341 | for (StationConsumeTime sct : list) { | 347 | for (StationConsumeTime sct : list) { |
| 342 | inD = sct.getInD1() + sct.getInD2(); | 348 | inD = sct.getInD1() + sct.getInD2(); |
| 343 | if (inD > normal) | 349 | if (inD > normal) |
| 344 | - sct.setSeconds((int) (sct.getSeconds() + ((inD - normal) / 10))); | 350 | + sct.setSeconds((int) (sct.getSeconds() + ((inD - normal) / IN_STATION_SPEED))); |
| 345 | 351 | ||
| 346 | ns.add(sct.getSeconds()); | 352 | ns.add(sct.getSeconds()); |
| 347 | } | 353 | } |
src/main/java/com/bsth/entity/GpsEntity.java
| @@ -71,6 +71,11 @@ public class GpsEntity implements Serializable { | @@ -71,6 +71,11 @@ public class GpsEntity implements Serializable { | ||
| 71 | */ | 71 | */ |
| 72 | private Double outStationDistance; | 72 | private Double outStationDistance; |
| 73 | 73 | ||
| 74 | + /** | ||
| 75 | + * 进站时间 | ||
| 76 | + */ | ||
| 77 | + private Long inStationTime; | ||
| 78 | + | ||
| 74 | private int version; | 79 | private int version; |
| 75 | 80 | ||
| 76 | /*** gps是否有效 设备端发送的状态*/ | 81 | /*** gps是否有效 设备端发送的状态*/ |
| @@ -109,6 +114,11 @@ public class GpsEntity implements Serializable { | @@ -109,6 +114,11 @@ public class GpsEntity implements Serializable { | ||
| 109 | private int seconds; | 114 | private int seconds; |
| 110 | 115 | ||
| 111 | /** | 116 | /** |
| 117 | + * 到下一站的时间,秒(信息发布用,离线时,该字段会被平滑过渡) | ||
| 118 | + */ | ||
| 119 | + private Integer seconds2; | ||
| 120 | + | ||
| 121 | + /** | ||
| 112 | * 是否对外发布 | 122 | * 是否对外发布 |
| 113 | */ | 123 | */ |
| 114 | private boolean release = true; | 124 | private boolean release = true; |
| @@ -139,19 +149,28 @@ public class GpsEntity implements Serializable { | @@ -139,19 +149,28 @@ public class GpsEntity implements Serializable { | ||
| 139 | return gps; | 149 | return gps; |
| 140 | } | 150 | } |
| 141 | 151 | ||
| 142 | - public void setStationInfo(StationRoute s){ | 152 | + public void setStationInfo(StationRoute s) { |
| 143 | this.stationCode = s.getStationCode(); | 153 | this.stationCode = s.getStationCode(); |
| 144 | this.stationName = s.getName(); | 154 | this.stationName = s.getName(); |
| 145 | this.stationNo = s.getSerialNo(); | 155 | this.stationNo = s.getSerialNo(); |
| 146 | } | 156 | } |
| 147 | 157 | ||
| 148 | - public void setStationInfo(GpsEntity prev){ | 158 | + public void setStationInfo(GpsEntity prev) { |
| 149 | this.stationCode = prev.stationCode; | 159 | this.stationCode = prev.stationCode; |
| 150 | this.stationName = prev.stationName; | 160 | this.stationName = prev.stationName; |
| 151 | this.stationNo = prev.stationNo; | 161 | this.stationNo = prev.stationNo; |
| 152 | } | 162 | } |
| 153 | 163 | ||
| 154 | - public Point getPoint(){ | 164 | + public void smoothTransition(long t) { |
| 165 | + int diff = (int) (t - timestamp), newSeconds; | ||
| 166 | + //掉线1分半的,平滑过渡一下预测时间 | ||
| 167 | + if (diff > 1000 * 60 * 1.5) { | ||
| 168 | + newSeconds = seconds - (diff / 1000 - 15); | ||
| 169 | + seconds2 = newSeconds < 0 ? 0 : newSeconds; | ||
| 170 | + } | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + public Point getPoint() { | ||
| 155 | return new Point(lon, lat); | 174 | return new Point(lon, lat); |
| 156 | } | 175 | } |
| 157 | 176 | ||
| @@ -363,4 +382,19 @@ public class GpsEntity implements Serializable { | @@ -363,4 +382,19 @@ public class GpsEntity implements Serializable { | ||
| 363 | this.release = release; | 382 | this.release = release; |
| 364 | } | 383 | } |
| 365 | 384 | ||
| 385 | + public Long getInStationTime() { | ||
| 386 | + return inStationTime; | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + public void setInStationTime(Long inStationTime) { | ||
| 390 | + this.inStationTime = inStationTime; | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + public Integer getSeconds2() { | ||
| 394 | + return seconds2; | ||
| 395 | + } | ||
| 396 | + | ||
| 397 | + public void setSeconds2(Integer seconds2) { | ||
| 398 | + this.seconds2 = seconds2; | ||
| 399 | + } | ||
| 366 | } | 400 | } |
src/main/resources/static/pages/h_consume/list.html
| @@ -71,7 +71,7 @@ | @@ -71,7 +71,7 @@ | ||
| 71 | <div class="form-group"> | 71 | <div class="form-group"> |
| 72 | <label class="bmd-label-floating">日期</label> | 72 | <label class="bmd-label-floating">日期</label> |
| 73 | <input type="text" name="rq" required class="form-control flatpickr_date" | 73 | <input type="text" name="rq" required class="form-control flatpickr_date" |
| 74 | - value="2018-06-20"> | 74 | + value="2018-06-27"> |
| 75 | </div> | 75 | </div> |
| 76 | </div> | 76 | </div> |
| 77 | <div class="col-md-2"> | 77 | <div class="col-md-2"> |
src/main/resources/static/pages/real/js/map.js
| @@ -99,12 +99,11 @@ var gb_real_gps_map = (function () { | @@ -99,12 +99,11 @@ var gb_real_gps_map = (function () { | ||
| 99 | m.setPosition(new BMap.Point(gps.bd_lon, gps.bd_lat)); | 99 | m.setPosition(new BMap.Point(gps.bd_lon, gps.bd_lat)); |
| 100 | w = m._icon_width; | 100 | w = m._icon_width; |
| 101 | m.setIcon(new BMap.Icon(createCarIconRotation(gps, w), new BMap.Size(w, 70))); | 101 | m.setIcon(new BMap.Icon(createCarIconRotation(gps, w), new BMap.Size(w, 70))); |
| 102 | - | ||
| 103 | - m._data = gps; | ||
| 104 | - if (m.infoWindow.isOpen()) | ||
| 105 | - bdOpenWindow(m); | ||
| 106 | } | 102 | } |
| 107 | 103 | ||
| 104 | + m._data = gps; | ||
| 105 | + if (m.infoWindow.isOpen()) | ||
| 106 | + bdOpenWindow(m); | ||
| 108 | devices.push(gps.deviceId); | 107 | devices.push(gps.deviceId); |
| 109 | } | 108 | } |
| 110 | 109 |
src/main/resources/static/pages/real/js/svg.js
| @@ -130,6 +130,7 @@ var gb_real_gps_svg = (function () { | @@ -130,6 +130,7 @@ var gb_real_gps_svg = (function () { | ||
| 130 | //时间处理 | 130 | //时间处理 |
| 131 | for (var i = 0, len = arr.length; i < len; i++) { | 131 | for (var i = 0, len = arr.length; i < len; i++) { |
| 132 | arr[i].secStr = seconds2Str(arr[i].seconds); | 132 | arr[i].secStr = seconds2Str(arr[i].seconds); |
| 133 | + arr[i].secStr2 = seconds2Str(arr[i].seconds2); | ||
| 133 | arr[i].zdsj = seconds2Str(rs.forecast[arr[i].deviceId]); | 134 | arr[i].zdsj = seconds2Str(rs.forecast[arr[i].deviceId]); |
| 134 | arr[i].timeStr = moment(arr[i].timestamp).format('YYYY-MM-DD HH:mm.ss'); | 135 | arr[i].timeStr = moment(arr[i].timestamp).format('YYYY-MM-DD HH:mm.ss'); |
| 135 | } | 136 | } |
| @@ -266,6 +267,8 @@ var gb_real_gps_svg = (function () { | @@ -266,6 +267,8 @@ var gb_real_gps_svg = (function () { | ||
| 266 | } | 267 | } |
| 267 | 268 | ||
| 268 | function seconds2Str(seconds) { | 269 | function seconds2Str(seconds) { |
| 270 | + if(!seconds) | ||
| 271 | + return null; | ||
| 269 | var minutes = parseInt(seconds / 60) | 272 | var minutes = parseInt(seconds / 60) |
| 270 | , s = seconds % 60; | 273 | , s = seconds % 60; |
| 271 | return minutes + '分' + s + "秒"; | 274 | return minutes + '分' + s + "秒"; |
src/main/resources/static/pages/real/main.html
| @@ -95,7 +95,7 @@ | @@ -95,7 +95,7 @@ | ||
| 95 | </td> | 95 | </td> |
| 96 | <td> | 96 | <td> |
| 97 | {{if gps.release}} | 97 | {{if gps.release}} |
| 98 | - {{gps.secStr}} | 98 | + {{gps.secStr2==null?gps.secStr:gps.secStr2}} |
| 99 | {{/if}} | 99 | {{/if}} |
| 100 | </td> | 100 | </td> |
| 101 | <td>{{gps.zdsj}}</td> | 101 | <td>{{gps.zdsj}}</td> |
| @@ -141,10 +141,10 @@ | @@ -141,10 +141,10 @@ | ||
| 141 | <p>距离下一站 {{distance}} 米</p> | 141 | <p>距离下一站 {{distance}} 米</p> |
| 142 | <hr> | 142 | <hr> |
| 143 | {{if secStr!=null}} | 143 | {{if secStr!=null}} |
| 144 | - <a href="javascript:;">预计 {{secStr}} 分钟到达下一站</a> | 144 | + <a href="javascript:;">预计 {{secStr2==null?secStr:secStr2}} 分钟到达下一站</a> |
| 145 | {{/if}} | 145 | {{/if}} |
| 146 | {{if zdsj!=null}} | 146 | {{if zdsj!=null}} |
| 147 | - <a href="javascript:;">预计 {{zdsj}} 分钟到达终点</a> | 147 | + <a href="javascript:;">预计 {{zdsj}} 分钟到达终点</a> |
| 148 | {{/if}} | 148 | {{/if}} |
| 149 | <hr> | 149 | <hr> |
| 150 | <a style="color: grey">{{timeStr}}</a> | 150 | <a style="color: grey">{{timeStr}}</a> |