| OLD | NEW | 
|     1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file |     1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 
|     2 // for details. All rights reserved. Use of this source code is governed by a |     2 // for details. All rights reserved. Use of this source code is governed by a | 
|     3 // BSD-style license that can be found in the LICENSE file. |     3 // BSD-style license that can be found in the LICENSE file. | 
|     4  |     4  | 
|     5 library debugger_page_element; |     5 library debugger_page_element; | 
|     6  |     6  | 
|     7 import 'dart:async'; |     7 import 'dart:async'; | 
|     8 import 'dart:svg'; |     8 import 'dart:svg'; | 
|     9 import 'dart:html'; |     9 import 'dart:html'; | 
|    10 import 'dart:math'; |    10 import 'dart:math'; | 
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   202       return new Future.value(null); |   202       return new Future.value(null); | 
|   203     } |   203     } | 
|   204     if (debugger.currentFrame == null) { |   204     if (debugger.currentFrame == null) { | 
|   205       debugger.console.print('No stack'); |   205       debugger.console.print('No stack'); | 
|   206       return new Future.value(null); |   206       return new Future.value(null); | 
|   207     } |   207     } | 
|   208     try { |   208     try { | 
|   209       debugger.downFrame(count); |   209       debugger.downFrame(count); | 
|   210       debugger.console.print('frame = ${debugger.currentFrame}'); |   210       debugger.console.print('frame = ${debugger.currentFrame}'); | 
|   211     } catch (e) { |   211     } catch (e) { | 
|   212       debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |   212       debugger.console.print( | 
 |   213           'frame must be in range [${e.start}..${e.end-1}]'); | 
|   213     } |   214     } | 
|   214     return new Future.value(null); |   215     return new Future.value(null); | 
|   215   } |   216   } | 
|   216  |   217  | 
|   217   String helpShort = 'Move down one or more frames (hotkey: [Page Down])'; |   218   String helpShort = 'Move down one or more frames (hotkey: [Page Down])'; | 
|   218  |   219  | 
|   219   String helpLong = 'Move down one or more frames.\n' |   220   String helpLong = 'Move down one or more frames.\n' | 
|   220       '\n' |   221       '\n' | 
|   221       'Hotkey: [Page Down]\n' |   222       'Hotkey: [Page Down]\n' | 
|   222       '\n' |   223       '\n' | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   236       return new Future.value(null); |   237       return new Future.value(null); | 
|   237     } |   238     } | 
|   238     if (debugger.currentFrame == null) { |   239     if (debugger.currentFrame == null) { | 
|   239       debugger.console.print('No stack'); |   240       debugger.console.print('No stack'); | 
|   240       return new Future.value(null); |   241       return new Future.value(null); | 
|   241     } |   242     } | 
|   242     try { |   243     try { | 
|   243       debugger.upFrame(count); |   244       debugger.upFrame(count); | 
|   244       debugger.console.print('frame = ${debugger.currentFrame}'); |   245       debugger.console.print('frame = ${debugger.currentFrame}'); | 
|   245     } on RangeError catch (e) { |   246     } on RangeError catch (e) { | 
|   246       debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |   247       debugger.console.print( | 
 |   248           'frame must be in range [${e.start}..${e.end-1}]'); | 
|   247     } |   249     } | 
|   248     return new Future.value(null); |   250     return new Future.value(null); | 
|   249   } |   251   } | 
|   250  |   252  | 
|   251   String helpShort = 'Move up one or more frames (hotkey: [Page Up])'; |   253   String helpShort = 'Move up one or more frames (hotkey: [Page Up])'; | 
|   252  |   254  | 
|   253   String helpLong = 'Move up one or more frames.\n' |   255   String helpLong = 'Move up one or more frames.\n' | 
|   254       '\n' |   256       '\n' | 
|   255       'Hotkey: [Page Up]\n' |   257       'Hotkey: [Page Up]\n' | 
|   256       '\n' |   258       '\n' | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   272       return new Future.value(null); |   274       return new Future.value(null); | 
|   273     } |   275     } | 
|   274     if (debugger.currentFrame == null) { |   276     if (debugger.currentFrame == null) { | 
|   275       debugger.console.print('No stack'); |   277       debugger.console.print('No stack'); | 
|   276       return new Future.value(null); |   278       return new Future.value(null); | 
|   277     } |   279     } | 
|   278     try { |   280     try { | 
|   279       debugger.currentFrame = frame; |   281       debugger.currentFrame = frame; | 
|   280       debugger.console.print('frame = ${debugger.currentFrame}'); |   282       debugger.console.print('frame = ${debugger.currentFrame}'); | 
|   281     } on RangeError catch (e) { |   283     } on RangeError catch (e) { | 
|   282       debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |   284       debugger.console.print( | 
 |   285           'frame must be in range [${e.start}..${e.end-1}]'); | 
|   283     } |   286     } | 
|   284     return new Future.value(null); |   287     return new Future.value(null); | 
|   285   } |   288   } | 
|   286  |   289  | 
|   287   String helpShort = 'Set the current frame'; |   290   String helpShort = 'Set the current frame'; | 
|   288  |   291  | 
|   289   String helpLong = 'Set the current frame.\n' |   292   String helpLong = 'Set the current frame.\n' | 
|   290       '\n' |   293       '\n' | 
|   291       'Syntax: frame <number>\n' |   294       'Syntax: frame <number>\n' | 
|   292       '        f <count>\n'; |   295       '        f <count>\n'; | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   396  |   399  | 
|   397   String helpLong = |   400   String helpLong = | 
|   398       'Continue running the isolate until it reaches the next source ' |   401       'Continue running the isolate until it reaches the next source ' | 
|   399       'location.\n' |   402       'location.\n' | 
|   400       '\n' |   403       '\n' | 
|   401       'Hotkey: [F10]\n' |   404       'Hotkey: [F10]\n' | 
|   402       '\n' |   405       '\n' | 
|   403       'Syntax: step\n'; |   406       'Syntax: step\n'; | 
|   404 } |   407 } | 
|   405  |   408  | 
 |   409 class RewindCommand extends DebuggerCommand { | 
 |   410   RewindCommand(Debugger debugger) : super(debugger, 'rewind', []); | 
 |   411  | 
 |   412   Future run(List<String> args) async { | 
 |   413     try { | 
 |   414       int count = 1; | 
 |   415       if (args.length == 1) { | 
 |   416         count = int.parse(args[0]); | 
 |   417       } else if (args.length > 1) { | 
 |   418         debugger.console.print('rewind expects 0 or 1 argument'); | 
 |   419         return; | 
 |   420       } else if (count < 1 || count > debugger.stackDepth) { | 
 |   421         debugger.console.print( | 
 |   422             'frame must be in range [1..${debugger.stackDepth - 1}]'); | 
 |   423         return; | 
 |   424       } | 
 |   425       await debugger.rewind(count); | 
 |   426     } on S.ServerRpcException catch(e) { | 
 |   427       if (e.code == S.ServerRpcException.kCannotResume) { | 
 |   428         debugger.console.printRed(e.data['details']); | 
 |   429       } else { | 
 |   430         rethrow; | 
 |   431       } | 
 |   432     } | 
 |   433   } | 
 |   434  | 
 |   435   String helpShort = 'Rewind the stack to a previous frame'; | 
 |   436  | 
 |   437   String helpLong = | 
 |   438       'Rewind the stack to a previous frame.\n' | 
 |   439       '\n' | 
 |   440       'Syntax: rewind\n' | 
 |   441       '        rewind <count>\n'; | 
 |   442 } | 
 |   443  | 
 |   444 class ReloadCommand extends DebuggerCommand { | 
 |   445   ReloadCommand(Debugger debugger) : super(debugger, 'reload', []); | 
 |   446  | 
 |   447   Future run(List<String> args) async { | 
 |   448     try { | 
 |   449       int count = 1; | 
 |   450       if (args.length > 0) { | 
 |   451         debugger.console.print('reload expects no arguments'); | 
 |   452         return; | 
 |   453       } | 
 |   454       await debugger.isolate.reloadSources(); | 
 |   455       debugger.console.print('reload complete'); | 
 |   456       await debugger.refreshStack(); | 
 |   457     } on S.ServerRpcException catch(e) { | 
 |   458       if (e.code == S.ServerRpcException.kIsolateReloadBarred || | 
 |   459           e.code == S.ServerRpcException.kIsolateReloadFailed || | 
 |   460           e.code == S.ServerRpcException.kIsolateIsReloading) { | 
 |   461         debugger.console.printRed(e.data['details']); | 
 |   462       } else { | 
 |   463         rethrow; | 
 |   464       } | 
 |   465     } | 
 |   466   } | 
 |   467  | 
 |   468   String helpShort = 'Reload the sources for the current isolate'; | 
 |   469  | 
 |   470   String helpLong = | 
 |   471       'Reload the sources for the current isolate.\n' | 
 |   472       '\n' | 
 |   473       'Syntax: reload\n'; | 
 |   474 } | 
 |   475  | 
|   406 class ClsCommand extends DebuggerCommand { |   476 class ClsCommand extends DebuggerCommand { | 
|   407   ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} |   477   ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} | 
|   408  |   478  | 
|   409   Future run(List<String> args) { |   479   Future run(List<String> args) { | 
|   410     debugger.console.clear(); |   480     debugger.console.clear(); | 
|   411     debugger.console.newline(); |   481     debugger.console.newline(); | 
|   412     return new Future.value(null); |   482     return new Future.value(null); | 
|   413   } |   483   } | 
|   414  |   484  | 
|   415   String helpShort = 'Clear the console'; |   485   String helpShort = 'Clear the console'; | 
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   656             debugger.console.print('Unable to set breakpoint at ${loc}'); |   726             debugger.console.print('Unable to set breakpoint at ${loc}'); | 
|   657           } else { |   727           } else { | 
|   658             rethrow; |   728             rethrow; | 
|   659           } |   729           } | 
|   660         } |   730         } | 
|   661       } else { |   731       } else { | 
|   662         assert(loc.script != null); |   732         assert(loc.script != null); | 
|   663         var script = loc.script; |   733         var script = loc.script; | 
|   664         await script.load(); |   734         await script.load(); | 
|   665         if (loc.line < 1 || loc.line > script.lines.length) { |   735         if (loc.line < 1 || loc.line > script.lines.length) { | 
|   666           debugger.console |   736           debugger.console.print( | 
|   667               .print('line number must be in range [1,${script.lines.length}]'); |   737               'line number must be in range [1..${script.lines.length}]'); | 
|   668           return; |   738           return; | 
|   669         } |   739         } | 
|   670         try { |   740         try { | 
|   671           await debugger.isolate.addBreakpoint(script, loc.line, loc.col); |   741           await debugger.isolate.addBreakpoint(script, loc.line, loc.col); | 
|   672         } on S.ServerRpcException catch (e) { |   742         } on S.ServerRpcException catch (e) { | 
|   673           if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { |   743           if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { | 
|   674             debugger.console.print('Unable to set breakpoint at ${loc}'); |   744             debugger.console.print('Unable to set breakpoint at ${loc}'); | 
|   675           } else { |   745           } else { | 
|   676             rethrow; |   746             rethrow; | 
|   677           } |   747           } | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   737     } |   807     } | 
|   738     if (loc.function != null) { |   808     if (loc.function != null) { | 
|   739       debugger.console.print('Ignoring breakpoint at $loc: ' |   809       debugger.console.print('Ignoring breakpoint at $loc: ' | 
|   740           'Clearing function breakpoints not yet implemented'); |   810           'Clearing function breakpoints not yet implemented'); | 
|   741       return; |   811       return; | 
|   742     } |   812     } | 
|   743  |   813  | 
|   744     var script = loc.script; |   814     var script = loc.script; | 
|   745     if (loc.line < 1 || loc.line > script.lines.length) { |   815     if (loc.line < 1 || loc.line > script.lines.length) { | 
|   746       debugger.console |   816       debugger.console | 
|   747           .print('line number must be in range [1,${script.lines.length}]'); |   817           .print('line number must be in range [1..${script.lines.length}]'); | 
|   748       return; |   818       return; | 
|   749     } |   819     } | 
|   750     var lineInfo = script.getLine(loc.line); |   820     var lineInfo = script.getLine(loc.line); | 
|   751     var bpts = lineInfo.breakpoints; |   821     var bpts = lineInfo.breakpoints; | 
|   752     var foundBreakpoint = false; |   822     var foundBreakpoint = false; | 
|   753     if (bpts != null) { |   823     if (bpts != null) { | 
|   754       var bptList = bpts.toList(); |   824       var bptList = bpts.toList(); | 
|   755       for (var bpt in bptList) { |   825       for (var bpt in bptList) { | 
|   756         if (loc.col == null || |   826         if (loc.col == null || | 
|   757             loc.col == script.tokenToCol(bpt.location.tokenPos)) { |   827             loc.col == script.tokenToCol(bpt.location.tokenPos)) { | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   892   String helpLong = 'Show current frame.\n' |   962   String helpLong = 'Show current frame.\n' | 
|   893       '\n' |   963       '\n' | 
|   894       'Syntax: info frame\n'; |   964       'Syntax: info frame\n'; | 
|   895 } |   965 } | 
|   896  |   966  | 
|   897 class IsolateCommand extends DebuggerCommand { |   967 class IsolateCommand extends DebuggerCommand { | 
|   898   IsolateCommand(Debugger debugger) |   968   IsolateCommand(Debugger debugger) | 
|   899       : super(debugger, 'isolate', [ |   969       : super(debugger, 'isolate', [ | 
|   900           new IsolateListCommand(debugger), |   970           new IsolateListCommand(debugger), | 
|   901           new IsolateNameCommand(debugger), |   971           new IsolateNameCommand(debugger), | 
|   902           new IsolateReloadCommand(debugger), |  | 
|   903         ]) { |   972         ]) { | 
|   904     alias = 'i'; |   973     alias = 'i'; | 
|   905   } |   974   } | 
|   906  |   975  | 
|   907   Future run(List<String> args) { |   976   Future run(List<String> args) { | 
|   908     if (args.length != 1) { |   977     if (args.length != 1) { | 
|   909       debugger.console.print('isolate expects one argument'); |   978       debugger.console.print('isolate expects one argument'); | 
|   910       return new Future.value(null); |   979       return new Future.value(null); | 
|   911     } |   980     } | 
|   912     var arg = args[0].trim(); |   981     var arg = args[0].trim(); | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1035     return debugger.isolate.setName(args[0]); |  1104     return debugger.isolate.setName(args[0]); | 
|  1036   } |  1105   } | 
|  1037  |  1106  | 
|  1038   String helpShort = 'Rename the current isolate'; |  1107   String helpShort = 'Rename the current isolate'; | 
|  1039  |  1108  | 
|  1040   String helpLong = 'Rename the current isolate.\n' |  1109   String helpLong = 'Rename the current isolate.\n' | 
|  1041       '\n' |  1110       '\n' | 
|  1042       'Syntax: isolate name <name>\n'; |  1111       'Syntax: isolate name <name>\n'; | 
|  1043 } |  1112 } | 
|  1044  |  1113  | 
|  1045 class IsolateReloadCommand extends DebuggerCommand { |  | 
|  1046   IsolateReloadCommand(Debugger debugger) : super(debugger, 'reload', []); |  | 
|  1047  |  | 
|  1048   Future run(List<String> args) async { |  | 
|  1049     if (debugger.isolate == null) { |  | 
|  1050       debugger.console.print('There is no current vm'); |  | 
|  1051       return; |  | 
|  1052     } |  | 
|  1053  |  | 
|  1054     await debugger.isolate.reloadSources(); |  | 
|  1055  |  | 
|  1056     debugger.console.print('Isolate reloading....'); |  | 
|  1057   } |  | 
|  1058  |  | 
|  1059   String helpShort = 'Reload the sources for the current isolate.'; |  | 
|  1060  |  | 
|  1061   String helpLong = 'Reload the sources for the current isolate.\n' |  | 
|  1062       '\n' |  | 
|  1063       'Syntax: reload\n'; |  | 
|  1064 } |  | 
|  1065  |  | 
|  1066 class InfoCommand extends DebuggerCommand { |  1114 class InfoCommand extends DebuggerCommand { | 
|  1067   InfoCommand(Debugger debugger) |  1115   InfoCommand(Debugger debugger) | 
|  1068       : super(debugger, 'info', [ |  1116       : super(debugger, 'info', [ | 
|  1069           new InfoBreakpointsCommand(debugger), |  1117           new InfoBreakpointsCommand(debugger), | 
|  1070           new InfoFrameCommand(debugger) |  1118           new InfoFrameCommand(debugger) | 
|  1071         ]); |  1119         ]); | 
|  1072  |  1120  | 
|  1073   Future run(List<String> args) { |  1121   Future run(List<String> args) { | 
|  1074     debugger.console.print("'info' expects a subcommand (see 'help info')"); |  1122     debugger.console.print("'info' expects a subcommand (see 'help info')"); | 
|  1075     return new Future.value(null); |  1123     return new Future.value(null); | 
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1364       new DeleteCommand(this), |  1412       new DeleteCommand(this), | 
|  1365       new DownCommand(this), |  1413       new DownCommand(this), | 
|  1366       new FinishCommand(this), |  1414       new FinishCommand(this), | 
|  1367       new FrameCommand(this), |  1415       new FrameCommand(this), | 
|  1368       new HelpCommand(this), |  1416       new HelpCommand(this), | 
|  1369       new InfoCommand(this), |  1417       new InfoCommand(this), | 
|  1370       new IsolateCommand(this), |  1418       new IsolateCommand(this), | 
|  1371       new LogCommand(this), |  1419       new LogCommand(this), | 
|  1372       new PauseCommand(this), |  1420       new PauseCommand(this), | 
|  1373       new PrintCommand(this), |  1421       new PrintCommand(this), | 
 |  1422       new ReloadCommand(this), | 
|  1374       new RefreshCommand(this), |  1423       new RefreshCommand(this), | 
 |  1424       new RewindCommand(this), | 
|  1375       new SetCommand(this), |  1425       new SetCommand(this), | 
|  1376       new SmartNextCommand(this), |  1426       new SmartNextCommand(this), | 
|  1377       new StepCommand(this), |  1427       new StepCommand(this), | 
|  1378       new SyncNextCommand(this), |  1428       new SyncNextCommand(this), | 
|  1379       new UpCommand(this), |  1429       new UpCommand(this), | 
|  1380       new VmCommand(this), |  1430       new VmCommand(this), | 
|  1381     ], _history); |  1431     ], _history); | 
|  1382     _consolePrinter = new _ConsoleStreamPrinter(this); |  1432     _consolePrinter = new _ConsoleStreamPrinter(this); | 
|  1383   } |  1433   } | 
|  1384  |  1434  | 
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1872       if (event is M.PauseExitEvent) { |  1922       if (event is M.PauseExitEvent) { | 
|  1873         console.print("Type 'continue' [F7] to exit the isolate"); |  1923         console.print("Type 'continue' [F7] to exit the isolate"); | 
|  1874         return new Future.value(null); |  1924         return new Future.value(null); | 
|  1875       } |  1925       } | 
|  1876       return isolate.stepInto(); |  1926       return isolate.stepInto(); | 
|  1877     } else { |  1927     } else { | 
|  1878       console.print('The program is already running'); |  1928       console.print('The program is already running'); | 
|  1879       return new Future.value(null); |  1929       return new Future.value(null); | 
|  1880     } |  1930     } | 
|  1881   } |  1931   } | 
 |  1932  | 
 |  1933   Future rewind(int count) { | 
 |  1934     if (isolatePaused()) { | 
 |  1935       var event = isolate.pauseEvent; | 
 |  1936       if (event is M.PauseExitEvent) { | 
 |  1937         console.print("Type 'continue' [F7] to exit the isolate"); | 
 |  1938         return new Future.value(null); | 
 |  1939       } | 
 |  1940       return isolate.rewind(count); | 
 |  1941     } else { | 
 |  1942       console.print('The program must be paused'); | 
 |  1943       return new Future.value(null); | 
 |  1944     } | 
 |  1945   } | 
|  1882 } |  1946 } | 
|  1883  |  1947  | 
|  1884 class DebuggerPageElement extends HtmlElement implements Renderable { |  1948 class DebuggerPageElement extends HtmlElement implements Renderable { | 
|  1885   static const tag = |  1949   static const tag = | 
|  1886       const Tag<DebuggerPageElement>('debugger-page', dependencies: const [ |  1950       const Tag<DebuggerPageElement>('debugger-page', dependencies: const [ | 
|  1887     NavTopMenuElement.tag, |  1951     NavTopMenuElement.tag, | 
|  1888     NavVMMenuElement.tag, |  1952     NavVMMenuElement.tag, | 
|  1889     NavIsolateMenuElement.tag, |  1953     NavIsolateMenuElement.tag, | 
|  1890     NavNotifyElement.tag, |  1954     NavNotifyElement.tag, | 
|  1891   ]); |  1955   ]); | 
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2506         ..classes = ['frameSummary'] |  2570         ..classes = ['frameSummary'] | 
|  2507         ..children = content |  2571         ..children = content | 
|  2508     ]; |  2572     ]; | 
|  2509   } |  2573   } | 
|  2510  |  2574  | 
|  2511   String makeExpandKey(String key) { |  2575   String makeExpandKey(String key) { | 
|  2512     return '${_frame.function.qualifiedName}/${key}'; |  2576     return '${_frame.function.qualifiedName}/${key}'; | 
|  2513   } |  2577   } | 
|  2514  |  2578  | 
|  2515   bool matchFrame(S.Frame newFrame) { |  2579   bool matchFrame(S.Frame newFrame) { | 
|  2516     return newFrame.function.id == _frame.function.id; |  2580     return (newFrame.function.id == _frame.function.id && | 
 |  2581             newFrame.location.script.id == | 
 |  2582             frame.location.script.id); | 
|  2517   } |  2583   } | 
|  2518  |  2584  | 
|  2519   void updateFrame(S.Frame newFrame) { |  2585   void updateFrame(S.Frame newFrame) { | 
|  2520     assert(matchFrame(newFrame)); |  2586     assert(matchFrame(newFrame)); | 
|  2521     _frame = newFrame; |  2587     _frame = newFrame; | 
|  2522   } |  2588   } | 
|  2523  |  2589  | 
|  2524   S.Script get script => _frame.location.script; |  2590   S.Script get script => _frame.location.script; | 
|  2525  |  2591  | 
|  2526   int _varsTop(varsDiv) { |  2592   int _varsTop(varsDiv) { | 
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3190   ..setAttribute('height', '24') |  3256   ..setAttribute('height', '24') | 
|  3191   ..children = [ |  3257   ..children = [ | 
|  3192     new PathElement() |  3258     new PathElement() | 
|  3193       ..setAttribute( |  3259       ..setAttribute( | 
|  3194           'd', |  3260           'd', | 
|  3195           'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' |  3261           'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' | 
|  3196           '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' |  3262           '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' | 
|  3197           '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' |  3263           '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' | 
|  3198           '9h2V7h-2v2z') |  3264           '9h2V7h-2v2z') | 
|  3199   ]; |  3265   ]; | 
| OLD | NEW |