omega.js 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
  1. (function() {
  2. var attachedPrefix, charCodeUnderscore, colors, profileColorPalette, profileColors;
  3. angular.module('omega').constant('builtinProfiles', OmegaPac.Profiles.builtinProfiles);
  4. profileColors = ['#9ce', '#9d9', '#fa8', '#fe9', '#d497ee', '#47b', '#5b5', '#d63', '#ca0'];
  5. colors = [].concat(profileColors);
  6. profileColorPalette = ((function() {
  7. var _results;
  8. _results = [];
  9. while (colors.length) {
  10. _results.push(colors.splice(0, 3));
  11. }
  12. return _results;
  13. })());
  14. angular.module('omega').constant('profileColors', profileColors);
  15. angular.module('omega').constant('profileColorPalette', profileColorPalette);
  16. attachedPrefix = '__ruleListOf_';
  17. angular.module('omega').constant('getAttachedName', function(name) {
  18. return attachedPrefix + name;
  19. });
  20. angular.module('omega').constant('getParentName', function(name) {
  21. if (name.indexOf(attachedPrefix) === 0) {
  22. return name.substr(attachedPrefix.length);
  23. } else {
  24. return void 0;
  25. }
  26. });
  27. charCodeUnderscore = '_'.charCodeAt(0);
  28. angular.module('omega').constant('charCodeUnderscore', charCodeUnderscore);
  29. angular.module('omega').constant('isProfileNameHidden', function(name) {
  30. return name.charCodeAt(0) === charCodeUnderscore;
  31. });
  32. angular.module('omega').constant('isProfileNameReserved', function(name) {
  33. return name.charCodeAt(0) === charCodeUnderscore && name.charCodeAt(1) === charCodeUnderscore;
  34. });
  35. angular.module('omega').config(function($stateProvider, $urlRouterProvider, $httpProvider, $animateProvider, $compileProvider) {
  36. $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|moz-extension):/);
  37. $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension|moz-extension):/);
  38. $animateProvider.classNameFilter(/angular-animate/);
  39. $urlRouterProvider.otherwise('/about');
  40. $urlRouterProvider.otherwise(function($injector, $location) {
  41. if ($location.path() === '') {
  42. return $injector.get('omegaTarget').lastUrl() || '/about';
  43. } else {
  44. return '/about';
  45. }
  46. });
  47. return $stateProvider.state('ui', {
  48. url: '/ui',
  49. templateUrl: 'partials/ui.html'
  50. }).state('general', {
  51. url: '/general',
  52. templateUrl: 'partials/general.html'
  53. }).state('io', {
  54. url: '/io',
  55. templateUrl: 'partials/io.html',
  56. controller: 'IoCtrl'
  57. }).state('profile', {
  58. url: '/profile/*name',
  59. templateUrl: 'partials/profile.html',
  60. controller: 'ProfileCtrl'
  61. }).state('about', {
  62. url: '/about',
  63. templateUrl: 'partials/about.html',
  64. controller: 'AboutCtrl'
  65. });
  66. });
  67. angular.module('omega').factory('$exceptionHandler', function($log) {
  68. return function(exception, cause) {
  69. if (exception.message === 'transition aborted') {
  70. return;
  71. }
  72. if (exception.message === 'transition superseded') {
  73. return;
  74. }
  75. if (exception.message === 'transition prevented') {
  76. return;
  77. }
  78. if (exception.message === 'transition failed') {
  79. return;
  80. }
  81. return $log.error(exception, cause);
  82. };
  83. });
  84. angular.module('omega').factory('omegaDebug', function($window, $rootScope, $injector) {
  85. var omegaDebug, _ref;
  86. omegaDebug = (_ref = $window.OmegaDebug) != null ? _ref : {};
  87. if (omegaDebug.downloadLog == null) {
  88. omegaDebug.downloadLog = function() {
  89. var blob, downloadFile, _ref1;
  90. downloadFile = (_ref1 = $injector.get('downloadFile')) != null ? _ref1 : saveAs;
  91. blob = new Blob([localStorage['log']], {
  92. type: "text/plain;charset=utf-8"
  93. });
  94. return downloadFile(blob, "OmegaLog_" + (Date.now()) + ".txt");
  95. };
  96. }
  97. if (omegaDebug.reportIssue == null) {
  98. omegaDebug.reportIssue = function() {
  99. $window.open('https://github.com/FelisCatus/SwitchyOmega/issues/new?title=&body=');
  100. };
  101. }
  102. if (omegaDebug.resetOptions == null) {
  103. omegaDebug.resetOptions = function() {
  104. return $rootScope.resetOptions();
  105. };
  106. }
  107. return omegaDebug;
  108. });
  109. angular.module('omega').factory('downloadFile', function() {
  110. var _ref;
  111. if ((typeof browser !== "undefined" && browser !== null ? (_ref = browser.downloads) != null ? _ref.download : void 0 : void 0) != null) {
  112. return function(blob, filename) {
  113. var url;
  114. url = URL.createObjectURL(blob);
  115. if (filename) {
  116. return browser.downloads.download({
  117. url: url,
  118. filename: filename
  119. });
  120. } else {
  121. return browser.downloads.download({
  122. url: url
  123. });
  124. }
  125. };
  126. } else {
  127. return function(blob, filename) {
  128. var noAutoBom;
  129. noAutoBom = true;
  130. return saveAs(blob, filename, noAutoBom);
  131. };
  132. }
  133. });
  134. }).call(this);
  135. (function() {
  136. angular.module('omega').controller('AboutCtrl', function($scope, $rootScope, $modal, omegaDebug) {
  137. var _;
  138. $scope.downloadLog = omegaDebug.downloadLog;
  139. $scope.reportIssue = omegaDebug.reportIssue;
  140. $scope.showResetOptionsModal = function() {
  141. return $modal.open({
  142. templateUrl: 'partials/reset_options_confirm.html'
  143. }).result.then(function() {
  144. return omegaDebug.resetOptions();
  145. });
  146. };
  147. try {
  148. return $scope.version = omegaDebug.getProjectVersion();
  149. } catch (_error) {
  150. _ = _error;
  151. return $scope.version = '?.?.?';
  152. }
  153. });
  154. }).call(this);
  155. (function() {
  156. angular.module('omega').controller('FixedProfileCtrl', function($scope, $modal, trFilter) {
  157. var defaultLabel, defaultPort, onBypassListChange, onProxyChange, proxyProperties, scheme, socks5AuthSupported, _fn, _i, _j, _len, _len1, _ref, _ref1, _ref2;
  158. $scope.urlSchemes = ['', 'http', 'https', 'ftp'];
  159. $scope.urlSchemeDefault = 'fallbackProxy';
  160. proxyProperties = {
  161. '': 'fallbackProxy',
  162. 'http': 'proxyForHttp',
  163. 'https': 'proxyForHttps',
  164. 'ftp': 'proxyForFtp'
  165. };
  166. $scope.schemeDisp = {
  167. '': null,
  168. 'http': 'http://',
  169. 'https': 'https://',
  170. 'ftp': 'ftp://'
  171. };
  172. defaultPort = {
  173. 'http': 80,
  174. 'https': 443,
  175. 'socks4': 1080,
  176. 'socks5': 1080
  177. };
  178. $scope.showAdvanced = false;
  179. $scope.optionsForScheme = {};
  180. _ref = $scope.urlSchemes;
  181. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  182. scheme = _ref[_i];
  183. defaultLabel = scheme ? trFilter('options_protocol_useDefault') : trFilter('options_protocol_direct');
  184. $scope.optionsForScheme[scheme] = [
  185. {
  186. label: defaultLabel,
  187. value: void 0
  188. }, {
  189. label: 'HTTP',
  190. value: 'http'
  191. }, {
  192. label: 'HTTPS',
  193. value: 'https'
  194. }, {
  195. label: 'SOCKS4',
  196. value: 'socks4'
  197. }, {
  198. label: 'SOCKS5',
  199. value: 'socks5'
  200. }
  201. ];
  202. }
  203. $scope.proxyEditors = {};
  204. socks5AuthSupported = ((typeof browser !== "undefined" && browser !== null ? (_ref1 = browser.proxy) != null ? _ref1.register : void 0 : void 0) != null);
  205. $scope.authSupported = {
  206. "http": true,
  207. "https": true,
  208. "socks5": socks5AuthSupported
  209. };
  210. $scope.isProxyAuthActive = function(scheme) {
  211. var _ref2;
  212. return ((_ref2 = $scope.profile.auth) != null ? _ref2[proxyProperties[scheme]] : void 0) != null;
  213. };
  214. $scope.editProxyAuth = function(scheme) {
  215. var auth, prop, proxy, scope, _ref2;
  216. prop = proxyProperties[scheme];
  217. proxy = $scope.profile[prop];
  218. scope = $scope.$new('isolate');
  219. scope.proxy = proxy;
  220. auth = (_ref2 = $scope.profile.auth) != null ? _ref2[prop] : void 0;
  221. scope.auth = auth && angular.copy(auth);
  222. scope.authSupported = $scope.authSupported[proxy.scheme];
  223. scope.protocolDisp = proxy.scheme;
  224. return $modal.open({
  225. templateUrl: 'partials/fixed_auth_edit.html',
  226. scope: scope,
  227. size: scope.authSupported ? 'sm' : 'lg'
  228. }).result.then(function(auth) {
  229. var _base;
  230. if (!(auth != null ? auth.username : void 0)) {
  231. if ($scope.profile.auth) {
  232. return $scope.profile.auth[prop] = void 0;
  233. }
  234. } else {
  235. if ((_base = $scope.profile).auth == null) {
  236. _base.auth = {};
  237. }
  238. return $scope.profile.auth[prop] = auth;
  239. }
  240. });
  241. };
  242. onProxyChange = function(proxyEditors, oldProxyEditors) {
  243. var proxy, _base, _j, _len1, _name, _ref2, _ref3, _results;
  244. if (!proxyEditors) {
  245. return;
  246. }
  247. _ref2 = $scope.urlSchemes;
  248. _results = [];
  249. for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
  250. scheme = _ref2[_j];
  251. proxy = proxyEditors[scheme];
  252. if ($scope.profile.auth && !$scope.authSupported[proxy.scheme]) {
  253. delete $scope.profile.auth[proxyProperties[scheme]];
  254. }
  255. if (!proxy.scheme) {
  256. if (!scheme) {
  257. proxyEditors[scheme] = {};
  258. }
  259. delete $scope.profile[proxyProperties[scheme]];
  260. continue;
  261. } else if (!oldProxyEditors[scheme].scheme) {
  262. if (proxy.scheme === proxyEditors[''].scheme) {
  263. if (proxy.port == null) {
  264. proxy.port = proxyEditors[''].port;
  265. }
  266. }
  267. if (proxy.port == null) {
  268. proxy.port = defaultPort[proxy.scheme];
  269. }
  270. if (proxy.host == null) {
  271. proxy.host = (_ref3 = proxyEditors[''].host) != null ? _ref3 : 'example.com';
  272. }
  273. }
  274. _results.push((_base = $scope.profile)[_name = proxyProperties[scheme]] != null ? _base[_name] : _base[_name] = proxy);
  275. }
  276. return _results;
  277. };
  278. _ref2 = $scope.urlSchemes;
  279. _fn = function(scheme) {
  280. return $scope.$watch((function() {
  281. return $scope.profile[proxyProperties[scheme]];
  282. }), function(proxy) {
  283. if (scheme && proxy) {
  284. $scope.showAdvanced = true;
  285. }
  286. return $scope.proxyEditors[scheme] = proxy != null ? proxy : {};
  287. });
  288. };
  289. for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
  290. scheme = _ref2[_j];
  291. _fn(scheme);
  292. }
  293. $scope.$watch('proxyEditors', onProxyChange, true);
  294. onBypassListChange = function(list) {
  295. var item;
  296. return $scope.bypassList = ((function() {
  297. var _k, _len2, _results;
  298. _results = [];
  299. for (_k = 0, _len2 = list.length; _k < _len2; _k++) {
  300. item = list[_k];
  301. _results.push(item.pattern);
  302. }
  303. return _results;
  304. })()).join('\n');
  305. };
  306. $scope.$watch('profile.bypassList', onBypassListChange, true);
  307. return $scope.$watch('bypassList', function(bypassList, oldList) {
  308. var entry;
  309. if ((bypassList == null) || bypassList === oldList) {
  310. return;
  311. }
  312. return $scope.profile.bypassList = (function() {
  313. var _k, _len2, _ref3, _results;
  314. _ref3 = bypassList.split(/\r?\n/);
  315. _results = [];
  316. for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
  317. entry = _ref3[_k];
  318. if (entry) {
  319. _results.push({
  320. conditionType: "BypassCondition",
  321. pattern: entry
  322. });
  323. }
  324. }
  325. return _results;
  326. })();
  327. });
  328. });
  329. }).call(this);
  330. (function() {
  331. angular.module('omega').controller('IoCtrl', function($scope, $rootScope, $window, $http, omegaTarget, downloadFile) {
  332. omegaTarget.state('web.restoreOnlineUrl').then(function(url) {
  333. if (url) {
  334. return $scope.restoreOnlineUrl = url;
  335. }
  336. });
  337. $scope.exportOptions = function() {
  338. return $rootScope.applyOptionsConfirm().then(function() {
  339. var blob, content, plainOptions;
  340. plainOptions = angular.fromJson(angular.toJson($rootScope.options));
  341. content = JSON.stringify(plainOptions);
  342. blob = new Blob([content], {
  343. type: "text/plain;charset=utf-8"
  344. });
  345. return downloadFile(blob, "OmegaOptions.bak");
  346. });
  347. };
  348. $scope.importSuccess = function() {
  349. return $rootScope.showAlert({
  350. type: 'success',
  351. i18n: 'options_importSuccess',
  352. message: 'Options imported.'
  353. });
  354. };
  355. $scope.restoreLocal = function(content) {
  356. $scope.restoringLocal = true;
  357. return $rootScope.resetOptions(content).then((function() {
  358. return $scope.importSuccess();
  359. }), function() {
  360. return $scope.restoreLocalError();
  361. })["finally"](function() {
  362. return $scope.restoringLocal = false;
  363. });
  364. };
  365. $scope.restoreLocalError = function() {
  366. return $rootScope.showAlert({
  367. type: 'error',
  368. i18n: 'options_importFormatError',
  369. message: 'Invalid backup file!'
  370. });
  371. };
  372. $scope.downloadError = function() {
  373. return $rootScope.showAlert({
  374. type: 'error',
  375. i18n: 'options_importDownloadError',
  376. message: 'Error downloading backup file!'
  377. });
  378. };
  379. $scope.triggerFileInput = function() {
  380. angular.element('#restore-local-file').click();
  381. };
  382. $scope.restoreOnline = function() {
  383. omegaTarget.state('web.restoreOnlineUrl', $scope.restoreOnlineUrl);
  384. $scope.restoringOnline = true;
  385. return $http({
  386. method: 'GET',
  387. url: $scope.restoreOnlineUrl,
  388. cache: false,
  389. timeout: 10000,
  390. responseType: "text"
  391. }).then((function(result) {
  392. return $rootScope.resetOptions(result.data).then((function() {
  393. return $scope.importSuccess();
  394. }), function() {
  395. return $scope.restoreLocalError();
  396. });
  397. }), $scope.downloadError)["finally"](function() {
  398. return $scope.restoringOnline = false;
  399. });
  400. };
  401. $scope.enableOptionsSync = function(args) {
  402. var enable;
  403. enable = function() {
  404. return omegaTarget.setOptionsSync(true, args)["finally"](function() {
  405. return $window.location.reload();
  406. });
  407. };
  408. if (args != null ? args.force : void 0) {
  409. return enable();
  410. } else {
  411. return $rootScope.applyOptionsConfirm().then(enable);
  412. }
  413. };
  414. $scope.disableOptionsSync = function() {
  415. return omegaTarget.setOptionsSync(false).then(function() {
  416. return $rootScope.applyOptionsConfirm().then(function() {
  417. return $window.location.reload();
  418. });
  419. });
  420. };
  421. return $scope.resetOptionsSync = function() {
  422. return omegaTarget.resetOptionsSync().then(function() {
  423. return $rootScope.applyOptionsConfirm().then(function() {
  424. return $window.location.reload();
  425. });
  426. });
  427. };
  428. });
  429. }).call(this);
  430. (function() {
  431. var __hasProp = {}.hasOwnProperty;
  432. angular.module('omega').controller('MasterCtrl', function($scope, $rootScope, $window, $q, $modal, $state, profileColors, profileIcons, omegaTarget, $timeout, $location, $filter, getAttachedName, isProfileNameReserved, isProfileNameHidden, dispNameFilter, downloadFile) {
  433. var checkFormValid, diff, onOptionChange, showFirstRun, showFirstRunOnce, tr, type, _ref, _ref1, _ref2;
  434. if (((typeof browser !== "undefined" && browser !== null ? (_ref = browser.proxy) != null ? _ref.register : void 0 : void 0) != null) || ((typeof browser !== "undefined" && browser !== null ? (_ref1 = browser.proxy) != null ? _ref1.registerProxyScript : void 0 : void 0) != null)) {
  435. $scope.isExperimental = true;
  436. $scope.pacProfilesUnsupported = true;
  437. }
  438. tr = $filter('tr');
  439. $rootScope.options = null;
  440. omegaTarget.addOptionsChangeCallback(function(newOptions) {
  441. $rootScope.options = angular.copy(newOptions);
  442. $rootScope.optionsOld = angular.copy(newOptions);
  443. omegaTarget.state('syncOptions').then(function(syncOptions) {
  444. return $scope.syncOptions = syncOptions;
  445. });
  446. return $timeout(function() {
  447. $rootScope.optionsDirty = false;
  448. return showFirstRun();
  449. });
  450. });
  451. $rootScope.revertOptions = function() {
  452. return $window.location.reload();
  453. };
  454. $rootScope.exportScript = function(name) {
  455. var getProfileName;
  456. getProfileName = name ? $q.when(name) : omegaTarget.state('currentProfileName');
  457. return getProfileName.then(function(profileName) {
  458. var ast, blob, fileName, missingProfile, pac, profile, profileNotFound, _ref2;
  459. if (!profileName) {
  460. return;
  461. }
  462. profile = $rootScope.profileByName(profileName);
  463. if ((_ref2 = profile.profileType) === 'DirectProfile' || _ref2 === 'SystemProfile') {
  464. return;
  465. }
  466. missingProfile = null;
  467. profileNotFound = function(name) {
  468. missingProfile = name;
  469. return 'dumb';
  470. };
  471. ast = OmegaPac.PacGenerator.script($rootScope.options, profileName, {
  472. profileNotFound: profileNotFound
  473. });
  474. pac = ast.print_to_string({
  475. beautify: true,
  476. comments: true
  477. });
  478. pac = OmegaPac.PacGenerator.ascii(pac);
  479. blob = new Blob([pac], {
  480. type: "text/plain;charset=utf-8"
  481. });
  482. fileName = profileName.replace(/\W+/g, '_');
  483. downloadFile(blob, "OmegaProfile_" + fileName + ".pac");
  484. if (missingProfile) {
  485. return $timeout(function() {
  486. return $rootScope.showAlert({
  487. type: 'error',
  488. message: tr('options_profileNotFound', [missingProfile])
  489. });
  490. });
  491. }
  492. });
  493. };
  494. diff = jsondiffpatch.create({
  495. objectHash: function(obj) {
  496. return JSON.stringify(obj);
  497. },
  498. textDiff: {
  499. minLength: 1 / 0
  500. }
  501. });
  502. $rootScope.showAlert = function(alert) {
  503. return $timeout(function() {
  504. $scope.alert = alert;
  505. $scope.alertShown = true;
  506. $scope.alertShownAt = Date.now();
  507. $timeout($rootScope.hideAlert, 3000);
  508. });
  509. };
  510. $rootScope.hideAlert = function() {
  511. return $timeout(function() {
  512. if (Date.now() - $scope.alertShownAt >= 1000) {
  513. return $scope.alertShown = false;
  514. }
  515. });
  516. };
  517. checkFormValid = function() {
  518. var fields;
  519. fields = angular.element('.ng-invalid');
  520. if (fields.length > 0) {
  521. fields[0].focus();
  522. $rootScope.showAlert({
  523. type: 'error',
  524. i18n: 'options_formInvalid'
  525. });
  526. return false;
  527. }
  528. return true;
  529. };
  530. $rootScope.applyOptions = function() {
  531. var patch, plainOptions;
  532. if (!checkFormValid()) {
  533. return;
  534. }
  535. if ($rootScope.$broadcast('omegaApplyOptions').defaultPrevented) {
  536. return;
  537. }
  538. plainOptions = angular.fromJson(angular.toJson($rootScope.options));
  539. patch = diff.diff($rootScope.optionsOld, plainOptions);
  540. return omegaTarget.optionsPatch(patch).then(function() {
  541. return $rootScope.showAlert({
  542. type: 'success',
  543. i18n: 'options_saveSuccess'
  544. });
  545. });
  546. };
  547. $rootScope.resetOptions = function(options) {
  548. return omegaTarget.resetOptions(options).then(function() {
  549. return $rootScope.showAlert({
  550. type: 'success',
  551. i18n: 'options_resetSuccess'
  552. });
  553. })["catch"](function(err) {
  554. $rootScope.showAlert({
  555. type: 'error',
  556. message: err
  557. });
  558. return $q.reject(err);
  559. });
  560. };
  561. $rootScope.profileByName = function(name) {
  562. return OmegaPac.Profiles.byName(name, $rootScope.options);
  563. };
  564. $rootScope.systemProfile = $rootScope.profileByName('system');
  565. $rootScope.externalProfile = {
  566. color: '#49afcd',
  567. name: tr('popup_externalProfile'),
  568. profileType: 'FixedProfile',
  569. fallbackProxy: {
  570. host: "127.0.0.1",
  571. port: 42,
  572. scheme: "http"
  573. }
  574. };
  575. $rootScope.applyOptionsConfirm = function() {
  576. if (!checkFormValid()) {
  577. return $q.reject('form_invalid');
  578. }
  579. if (!$rootScope.optionsDirty) {
  580. return $q.when(true);
  581. }
  582. return $modal.open({
  583. templateUrl: 'partials/apply_options_confirm.html'
  584. }).result.then(function() {
  585. return $rootScope.applyOptions();
  586. });
  587. };
  588. $rootScope.newProfile = function() {
  589. var scope;
  590. scope = $rootScope.$new('isolate');
  591. scope.options = $rootScope.options;
  592. scope.isProfileNameReserved = isProfileNameReserved;
  593. scope.isProfileNameHidden = isProfileNameHidden;
  594. scope.profileByName = $rootScope.profileByName;
  595. scope.validateProfileName = {
  596. conflict: '!$value || !profileByName($value)',
  597. reserved: '!$value || !isProfileNameReserved($value)'
  598. };
  599. scope.profileIcons = profileIcons;
  600. scope.dispNameFilter = dispNameFilter;
  601. scope.options = $scope.options;
  602. scope.pacProfilesUnsupported = $scope.pacProfilesUnsupported;
  603. return $modal.open({
  604. templateUrl: 'partials/new_profile.html',
  605. scope: scope
  606. }).result.then(function(profile) {
  607. var choice;
  608. profile = OmegaPac.Profiles.create(profile);
  609. choice = Math.floor(Math.random() * profileColors.length);
  610. if (profile.color == null) {
  611. profile.color = profileColors[choice];
  612. }
  613. OmegaPac.Profiles.updateRevision(profile);
  614. $rootScope.options[OmegaPac.Profiles.nameAsKey(profile)] = profile;
  615. return $state.go('profile', {
  616. name: profile.name
  617. });
  618. });
  619. };
  620. $rootScope.replaceProfile = function(fromName, toName) {
  621. return $rootScope.applyOptionsConfirm().then(function() {
  622. var scope;
  623. scope = $rootScope.$new('isolate');
  624. scope.options = $rootScope.options;
  625. scope.fromName = fromName;
  626. scope.toName = toName;
  627. scope.profileByName = $rootScope.profileByName;
  628. scope.dispNameFilter = dispNameFilter;
  629. scope.options = $scope.options;
  630. scope.profileSelect = function(model) {
  631. return "<div omega-profile-select=\"options | profiles:profile\"\n ng-model=\"" + model + "\" options=\"options\"\n disp-name=\"dispNameFilter\" style=\"display: inline-block;\">\n</div>";
  632. };
  633. return $modal.open({
  634. templateUrl: 'partials/replace_profile.html',
  635. scope: scope
  636. }).result.then(function(_arg) {
  637. var fromName, toName;
  638. fromName = _arg.fromName, toName = _arg.toName;
  639. return omegaTarget.replaceRef(fromName, toName).then(function() {
  640. return $rootScope.showAlert({
  641. type: 'success',
  642. i18n: 'options_replaceProfileSuccess'
  643. });
  644. })["catch"](function(err) {
  645. return $rootScope.showAlert({
  646. type: 'error',
  647. message: err
  648. });
  649. });
  650. });
  651. });
  652. };
  653. $rootScope.renameProfile = function(fromName) {
  654. return $rootScope.applyOptionsConfirm().then(function() {
  655. var profile, scope;
  656. profile = $rootScope.profileByName(fromName);
  657. scope = $rootScope.$new('isolate');
  658. scope.options = $rootScope.options;
  659. scope.fromName = fromName;
  660. scope.isProfileNameReserved = isProfileNameReserved;
  661. scope.isProfileNameHidden = isProfileNameHidden;
  662. scope.profileByName = $rootScope.profileByName;
  663. scope.validateProfileName = {
  664. conflict: '!$value || $value == fromName || !profileByName($value)',
  665. reserved: '!$value || !isProfileNameReserved($value)'
  666. };
  667. scope.dispNameFilter = $scope.dispNameFilter;
  668. scope.options = $scope.options;
  669. return $modal.open({
  670. templateUrl: 'partials/rename_profile.html',
  671. scope: scope
  672. }).result.then(function(toName) {
  673. var attachedName, defaultProfileName, rename, toAttachedName;
  674. if (toName !== fromName) {
  675. rename = omegaTarget.renameProfile(fromName, toName);
  676. attachedName = getAttachedName(fromName);
  677. if ($rootScope.profileByName(attachedName)) {
  678. toAttachedName = getAttachedName(toName);
  679. defaultProfileName = void 0;
  680. if ($rootScope.profileByName(toAttachedName)) {
  681. defaultProfileName = profile.defaultProfileName;
  682. rename = rename.then(function() {
  683. var toAttachedKey;
  684. toAttachedKey = OmegaPac.Profiles.nameAsKey(toAttachedName);
  685. profile = $rootScope.profileByName(toName);
  686. profile.defaultProfileName = 'direct';
  687. OmegaPac.Profiles.updateRevision(profile);
  688. delete $rootScope.options[toAttachedKey];
  689. return $rootScope.applyOptions();
  690. });
  691. }
  692. rename = rename.then(function() {
  693. return omegaTarget.renameProfile(attachedName, toAttachedName);
  694. });
  695. if (defaultProfileName) {
  696. rename = rename.then(function() {
  697. profile = $rootScope.profileByName(toName);
  698. profile.defaultProfileName = defaultProfileName;
  699. return $rootScope.applyOptions();
  700. });
  701. }
  702. }
  703. return rename.then(function() {
  704. return $state.go('profile', {
  705. name: toName
  706. });
  707. })["catch"](function(err) {
  708. return $rootScope.showAlert({
  709. type: 'error',
  710. message: err
  711. });
  712. });
  713. }
  714. });
  715. });
  716. };
  717. $scope.updatingProfile = {};
  718. $rootScope.updateProfile = function(name) {
  719. return $rootScope.applyOptionsConfirm().then(function() {
  720. if (name != null) {
  721. $scope.updatingProfile[name] = true;
  722. } else {
  723. OmegaPac.Profiles.each($scope.options, function(key, profile) {
  724. if (!profile.builtin) {
  725. return $scope.updatingProfile[profile.name] = true;
  726. }
  727. });
  728. }
  729. return omegaTarget.updateProfile(name, 'bypass_cache').then(function(results) {
  730. var error, profileName, result, singleErr, success;
  731. success = 0;
  732. error = 0;
  733. for (profileName in results) {
  734. if (!__hasProp.call(results, profileName)) continue;
  735. result = results[profileName];
  736. if (result instanceof Error) {
  737. error++;
  738. } else {
  739. success++;
  740. }
  741. }
  742. if (error === 0) {
  743. return $rootScope.showAlert({
  744. type: 'success',
  745. i18n: 'options_profileDownloadSuccess'
  746. });
  747. } else {
  748. if (error === 1) {
  749. singleErr = results[OmegaPac.Profiles.nameAsKey(name)];
  750. if (singleErr) {
  751. return $q.reject(singleErr);
  752. }
  753. }
  754. return $q.reject(results);
  755. }
  756. })["catch"](function(err) {
  757. var message, _ref2, _ref3, _ref4;
  758. message = tr('options_profileDownloadError_' + err.name, [(_ref2 = (_ref3 = err.statusCode) != null ? _ref3 : (_ref4 = err.original) != null ? _ref4.statusCode : void 0) != null ? _ref2 : '']);
  759. if (message) {
  760. return $rootScope.showAlert({
  761. type: 'error',
  762. message: message
  763. });
  764. } else {
  765. return $rootScope.showAlert({
  766. type: 'error',
  767. i18n: 'options_profileDownloadError'
  768. });
  769. }
  770. })["finally"](function() {
  771. if (name != null) {
  772. return $scope.updatingProfile[name] = false;
  773. } else {
  774. return $scope.updatingProfile = {};
  775. }
  776. });
  777. });
  778. };
  779. onOptionChange = function(options, oldOptions) {
  780. if (options === oldOptions || (oldOptions == null)) {
  781. return;
  782. }
  783. return $rootScope.optionsDirty = true;
  784. };
  785. $rootScope.$watch('options', onOptionChange, true);
  786. $rootScope.$on('$stateChangeStart', function(event, _, __, fromState) {
  787. if (!checkFormValid()) {
  788. return event.preventDefault();
  789. }
  790. });
  791. $rootScope.$on('$stateChangeSuccess', function() {
  792. return omegaTarget.lastUrl($location.url());
  793. });
  794. $window.onbeforeunload = function() {
  795. if ($rootScope.optionsDirty) {
  796. return tr('options_optionsNotSaved');
  797. } else {
  798. return null;
  799. }
  800. };
  801. document.addEventListener('click', (function() {
  802. return $rootScope.hideAlert();
  803. }), false);
  804. $scope.profileIcons = profileIcons;
  805. $scope.dispNameFilter = dispNameFilter;
  806. _ref2 = OmegaPac.Profiles.formatByType;
  807. for (type in _ref2) {
  808. if (!__hasProp.call(_ref2, type)) continue;
  809. $scope.profileIcons[type] = $scope.profileIcons['RuleListProfile'];
  810. }
  811. $scope.alertIcons = {
  812. 'success': 'glyphicon-ok',
  813. 'warning': 'glyphicon-warning-sign',
  814. 'error': 'glyphicon-remove',
  815. 'danger': 'glyphicon-danger'
  816. };
  817. $scope.alertClassForType = function(type) {
  818. if (!type) {
  819. return '';
  820. }
  821. if (type === 'error') {
  822. type = 'danger';
  823. }
  824. return 'alert-' + type;
  825. };
  826. $scope.downloadIntervals = [15, 60, 180, 360, 720, 1440, -1];
  827. $scope.downloadIntervalI18n = function(interval) {
  828. return "options_downloadInterval_" + (interval < 0 ? "never" : interval);
  829. };
  830. $scope.openShortcutConfig = omegaTarget.openShortcutConfig.bind(omegaTarget);
  831. showFirstRunOnce = true;
  832. showFirstRun = function() {
  833. if (!showFirstRunOnce) {
  834. return;
  835. }
  836. showFirstRunOnce = false;
  837. return omegaTarget.state('firstRun').then(function(firstRun) {
  838. var profileName, scope;
  839. if (!firstRun) {
  840. return;
  841. }
  842. omegaTarget.state('firstRun', '');
  843. profileName = null;
  844. OmegaPac.Profiles.each($rootScope.options, function(key, profile) {
  845. if (!profileName && profile.profileType === 'FixedProfile') {
  846. return profileName = profile.name;
  847. }
  848. });
  849. if (!profileName) {
  850. return;
  851. }
  852. scope = $rootScope.$new('isolate');
  853. scope.upgrade = firstRun === 'upgrade';
  854. return $modal.open({
  855. templateUrl: 'partials/options_welcome.html',
  856. keyboard: false,
  857. scope: scope,
  858. backdrop: 'static',
  859. backdropClass: 'opacity-half'
  860. }).result.then(function(r) {
  861. switch (r) {
  862. case 'later':
  863. break;
  864. case 'show':
  865. return $state.go('profile', {
  866. name: profileName
  867. }).then(function() {
  868. return $script('js/options_guide.js');
  869. });
  870. }
  871. });
  872. });
  873. };
  874. return omegaTarget.refresh();
  875. });
  876. }).call(this);
  877. (function() {
  878. angular.module('omega').controller('PacProfileCtrl', function($scope, $modal) {
  879. var oldLastUpdate, oldPacScript, oldPacUrl, onProfileChange, set;
  880. $scope.urlRegex = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
  881. $scope.urlWithFile = /^(ftp|http|https|file):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
  882. $scope.isFileUrl = OmegaPac.Profiles.isFileUrl;
  883. $scope.pacUrlCtrl = {
  884. ctrl: null
  885. };
  886. set = OmegaPac.Profiles.referencedBySet($scope.profile, $scope.options);
  887. $scope.referenced = Object.keys(set).length > 0;
  888. oldPacUrl = null;
  889. oldLastUpdate = null;
  890. oldPacScript = null;
  891. onProfileChange = function(profile, oldProfile) {
  892. if (!(profile && oldProfile)) {
  893. return;
  894. }
  895. if (profile.pacUrl !== oldProfile.pacUrl) {
  896. if (profile.lastUpdate) {
  897. oldPacUrl = oldProfile.pacUrl;
  898. oldLastUpdate = profile.lastUpdate;
  899. oldPacScript = oldProfile.pacScript;
  900. profile.lastUpdate = null;
  901. } else if (oldPacUrl && profile.pacUrl === oldPacUrl) {
  902. profile.lastUpdate = oldLastUpdate;
  903. profile.pacScript = oldPacScript;
  904. }
  905. }
  906. return $scope.pacUrlIsFile = $scope.isFileUrl(profile.pacUrl);
  907. };
  908. $scope.$watch('profile', onProfileChange, true);
  909. return $scope.editProxyAuth = function(scheme) {
  910. var auth, prop, scope, _ref;
  911. prop = 'all';
  912. auth = (_ref = $scope.profile.auth) != null ? _ref[prop] : void 0;
  913. scope = $scope.$new('isolate');
  914. scope.auth = auth && angular.copy(auth);
  915. return $modal.open({
  916. templateUrl: 'partials/fixed_auth_edit.html',
  917. scope: scope,
  918. size: 'sm'
  919. }).result.then(function(auth) {
  920. var _base;
  921. if (!(auth != null ? auth.username : void 0)) {
  922. if ($scope.profile.auth) {
  923. return $scope.profile.auth[prop] = void 0;
  924. }
  925. } else {
  926. if ((_base = $scope.profile).auth == null) {
  927. _base.auth = {};
  928. }
  929. return $scope.profile.auth[prop] = auth;
  930. }
  931. });
  932. };
  933. });
  934. }).call(this);
  935. (function() {
  936. var __hasProp = {}.hasOwnProperty;
  937. angular.module('omega').controller('ProfileCtrl', function($scope, $stateParams, $location, $rootScope, $timeout, $state, $modal, profileColorPalette, getAttachedName, getParentName, getVirtualTarget) {
  938. var name, profileTemplates, unwatch;
  939. name = $stateParams.name;
  940. profileTemplates = {
  941. 'FixedProfile': 'profile_fixed.html',
  942. 'PacProfile': 'profile_pac.html',
  943. 'VirtualProfile': 'profile_virtual.html',
  944. 'SwitchProfile': 'profile_switch.html',
  945. 'RuleListProfile': 'profile_rule_list.html'
  946. };
  947. $scope.spectrumOptions = {
  948. localStorageKey: 'spectrum.profileColor',
  949. palette: profileColorPalette,
  950. preferredFormat: 'hex',
  951. showButtons: false,
  952. showInitial: true,
  953. showInput: true,
  954. showPalette: true,
  955. showSelectionPalette: true,
  956. maxSelectionSize: 5
  957. };
  958. $scope.getProfileColor = function() {
  959. var color, profile;
  960. color = void 0;
  961. profile = $scope.profile;
  962. while (profile) {
  963. color = profile.color;
  964. profile = getVirtualTarget(profile, $scope.options);
  965. }
  966. return color;
  967. };
  968. $scope.deleteProfile = function() {
  969. var key, parent, pname, profileName, refProfiles, refSet, refs, scope;
  970. profileName = $scope.profile.name;
  971. refs = OmegaPac.Profiles.referencedBySet(profileName, $rootScope.options);
  972. scope = $rootScope.$new('isolate');
  973. scope.profile = $scope.profile;
  974. scope.dispNameFilter = $scope.dispNameFilter;
  975. scope.options = $scope.options;
  976. if (Object.keys(refs).length > 0) {
  977. refSet = {};
  978. for (key in refs) {
  979. if (!__hasProp.call(refs, key)) continue;
  980. pname = refs[key];
  981. parent = getParentName(pname);
  982. if (parent) {
  983. key = OmegaPac.Profiles.nameAsKey(parent);
  984. pname = parent;
  985. }
  986. refSet[key] = pname;
  987. }
  988. refProfiles = [];
  989. for (key in refSet) {
  990. if (!__hasProp.call(refSet, key)) continue;
  991. refProfiles.push(OmegaPac.Profiles.byKey(key, $rootScope.options));
  992. }
  993. scope.refs = refProfiles;
  994. $modal.open({
  995. templateUrl: 'partials/cannot_delete_profile.html',
  996. scope: scope
  997. });
  998. } else {
  999. return $modal.open({
  1000. templateUrl: 'partials/delete_profile.html',
  1001. scope: scope
  1002. }).result.then(function() {
  1003. var attachedName, i, quickSwitch, _i, _ref;
  1004. attachedName = getAttachedName(profileName);
  1005. delete $rootScope.options[OmegaPac.Profiles.nameAsKey(attachedName)];
  1006. delete $rootScope.options[OmegaPac.Profiles.nameAsKey(profileName)];
  1007. if ($rootScope.options['-startupProfileName'] === profileName) {
  1008. $rootScope.options['-startupProfileName'] = "";
  1009. }
  1010. quickSwitch = $rootScope.options['-quickSwitchProfiles'];
  1011. for (i = _i = 0, _ref = quickSwitch.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
  1012. if (profileName === quickSwitch[i]) {
  1013. quickSwitch.splice(i, 1);
  1014. break;
  1015. }
  1016. }
  1017. return $state.go('ui');
  1018. });
  1019. }
  1020. };
  1021. $scope.watchAndUpdateRevision = function(expression) {
  1022. var onChange, revisionChanged;
  1023. revisionChanged = false;
  1024. onChange = function(profile, oldProfile) {
  1025. if (profile === oldProfile || !profile || !oldProfile) {
  1026. return profile;
  1027. }
  1028. if (revisionChanged && profile.revision !== oldProfile.revision) {
  1029. return revisionChanged = false;
  1030. } else {
  1031. OmegaPac.Profiles.updateRevision(profile);
  1032. return revisionChanged = true;
  1033. }
  1034. };
  1035. return this.$watch(expression, onChange, true);
  1036. };
  1037. $scope.exportRuleList = null;
  1038. $scope.exportRuleListOptions = null;
  1039. $scope.setExportRuleListHandler = function(exportRuleList, options) {
  1040. $scope.exportRuleList = exportRuleList;
  1041. return $scope.exportRuleListOptions = options;
  1042. };
  1043. return unwatch = $scope.$watch((function() {
  1044. var _ref;
  1045. return (_ref = $scope.options) != null ? _ref['+' + name] : void 0;
  1046. }), function(profile) {
  1047. var templ, type, unwatch2, _ref;
  1048. if (!profile) {
  1049. if ($scope.options) {
  1050. unwatch();
  1051. $location.path('/');
  1052. } else {
  1053. unwatch2 = $scope.$watch('options', function() {
  1054. if ($scope.options) {
  1055. unwatch2();
  1056. if (!$scope.options['+' + name]) {
  1057. unwatch();
  1058. return $location.path('/');
  1059. }
  1060. }
  1061. });
  1062. }
  1063. return;
  1064. }
  1065. if (OmegaPac.Profiles.formatByType[profile.profileType]) {
  1066. profile.format = OmegaPac.Profiles.formatByType[profile.profileType];
  1067. profile.profileType = 'RuleListProfile';
  1068. }
  1069. $scope.profile = profile;
  1070. type = $scope.profile.profileType;
  1071. templ = (_ref = profileTemplates[type]) != null ? _ref : 'profile_unsupported.html';
  1072. $scope.profileTemplate = 'partials/' + templ;
  1073. $scope.scriptable = true;
  1074. return $scope.watchAndUpdateRevision('profile');
  1075. });
  1076. });
  1077. }).call(this);
  1078. (function() {
  1079. angular.module('omega').controller('QuickSwitchCtrl', function($scope, $filter) {
  1080. $scope.sortableOptions = {
  1081. tolerance: 'pointer',
  1082. axis: 'y',
  1083. forceHelperSize: true,
  1084. forcePlaceholderSize: true,
  1085. connectWith: '.cycle-profile-container',
  1086. containment: '#quick-switch-settings'
  1087. };
  1088. return $scope.$watchCollection('options', function(options) {
  1089. var profile;
  1090. if (options == null) {
  1091. return;
  1092. }
  1093. return $scope.notCycledProfiles = (function() {
  1094. var _i, _len, _ref, _results;
  1095. _ref = $filter('profiles')(options, 'all');
  1096. _results = [];
  1097. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  1098. profile = _ref[_i];
  1099. if (options["-quickSwitchProfiles"].indexOf(profile.name) < 0) {
  1100. _results.push(profile.name);
  1101. }
  1102. }
  1103. return _results;
  1104. })();
  1105. });
  1106. });
  1107. }).call(this);
  1108. (function() {
  1109. angular.module('omega').controller('RuleListProfileCtrl', function($scope) {
  1110. return $scope.ruleListFormats = OmegaPac.Profiles.ruleListFormats;
  1111. });
  1112. }).call(this);
  1113. (function() {
  1114. var __hasProp = {}.hasOwnProperty;
  1115. angular.module('omega').controller('SwitchProfileCtrl', function($scope, $rootScope, $location, $timeout, $q, $modal, profileIcons, getAttachedName, omegaTarget, trFilter, downloadFile) {
  1116. var advancedConditionTypesExpanded, attachedReady, attachedReadyDefer, basicConditionTypeSet, basicConditionTypesExpanded, expandGroups, exportLegacyRuleList, exportRuleList, oldLastUpdate, oldRuleList, oldSourceUrl, onAttachedChange, parseOmegaRules, parseSource, rulesReady, rulesReadyDefer, stateEditorKey, stopWatchingForRules, type, unwatchRules, unwatchRulesShowNote, updateHasConditionTypes, _i, _len;
  1117. $scope.ruleListFormats = OmegaPac.Profiles.ruleListFormats;
  1118. exportRuleList = function() {
  1119. var blob, eol, fileName, info, text;
  1120. text = OmegaPac.RuleList.Switchy.compose({
  1121. rules: $scope.profile.rules,
  1122. defaultProfileName: $scope.attachedOptions.defaultProfileName
  1123. });
  1124. eol = '\r\n';
  1125. info = '\n';
  1126. info += '; Require: SwitchyOmega >= 2.3.2' + eol;
  1127. info += ("; Date: " + (new Date().toLocaleDateString())) + eol;
  1128. info += ("; Usage: " + (trFilter('ruleList_usageUrl'))) + eol;
  1129. text = text.replace('\n', info);
  1130. blob = new Blob([text], {
  1131. type: "text/plain;charset=utf-8"
  1132. });
  1133. fileName = $scope.profile.name.replace(/\W+/g, '_');
  1134. return downloadFile(blob, "OmegaRules_" + fileName + ".sorl");
  1135. };
  1136. exportLegacyRuleList = function() {
  1137. var blob, fileName, i, regexpRules, rule, text, wildcardRules, _i, _len, _ref;
  1138. wildcardRules = '';
  1139. regexpRules = '';
  1140. _ref = $scope.profile.rules;
  1141. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  1142. rule = _ref[_i];
  1143. i = '';
  1144. if (rule.profileName === $scope.attachedOptions.defaultProfileName) {
  1145. i = '!';
  1146. }
  1147. switch (rule.condition.conditionType) {
  1148. case 'HostWildcardCondition':
  1149. wildcardRules += i + '@*://' + rule.condition.pattern + '/*' + '\r\n';
  1150. break;
  1151. case 'UrlWildcardCondition':
  1152. wildcardRules += i + '@' + rule.condition.pattern + '\r\n';
  1153. break;
  1154. case 'UrlRegexCondition':
  1155. regexpRules += i + rule.condition.pattern + '\r\n';
  1156. }
  1157. }
  1158. text = "; Summary: Proxy Switchy! Exported Rule List\n; Date: " + (new Date().toLocaleDateString()) + "\n; Website: " + (trFilter('ruleList_usageUrl')) + "\n\n#BEGIN\n\n[wildcard]\n" + wildcardRules + "\n[regexp]\n" + regexpRules + "\n#END";
  1159. blob = new Blob([text], {
  1160. type: "text/plain;charset=utf-8"
  1161. });
  1162. fileName = $scope.profile.name.replace(/\W+/g, '_');
  1163. return downloadFile(blob, "SwitchyRules_" + fileName + ".ssrl");
  1164. };
  1165. $scope.conditionHelp = {
  1166. show: $location.search().help === 'condition'
  1167. };
  1168. $scope.basicConditionTypes = [
  1169. {
  1170. group: 'default',
  1171. types: ['HostWildcardCondition', 'UrlWildcardCondition', 'UrlRegexCondition', 'FalseCondition']
  1172. }
  1173. ];
  1174. $scope.advancedConditionTypes = [
  1175. {
  1176. group: 'host',
  1177. types: ['HostWildcardCondition', 'HostRegexCondition', 'HostLevelsCondition', 'IpCondition']
  1178. }, {
  1179. group: 'url',
  1180. types: ['UrlWildcardCondition', 'UrlRegexCondition', 'KeywordCondition']
  1181. }, {
  1182. group: 'special',
  1183. types: ['WeekdayCondition', 'TimeCondition', 'FalseCondition']
  1184. }
  1185. ];
  1186. expandGroups = function(groups) {
  1187. var group, result, type, _i, _j, _len, _len1, _ref;
  1188. result = [];
  1189. for (_i = 0, _len = groups.length; _i < _len; _i++) {
  1190. group = groups[_i];
  1191. _ref = group.types;
  1192. for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
  1193. type = _ref[_j];
  1194. result.push({
  1195. type: type,
  1196. group: 'condition_group_' + group.group
  1197. });
  1198. }
  1199. }
  1200. return result;
  1201. };
  1202. basicConditionTypesExpanded = expandGroups($scope.basicConditionTypes);
  1203. advancedConditionTypesExpanded = expandGroups($scope.advancedConditionTypes);
  1204. basicConditionTypeSet = {};
  1205. for (_i = 0, _len = basicConditionTypesExpanded.length; _i < _len; _i++) {
  1206. type = basicConditionTypesExpanded[_i];
  1207. basicConditionTypeSet[type.type] = type.type;
  1208. }
  1209. $scope.conditionTypes = basicConditionTypesExpanded;
  1210. $scope.showConditionTypes = 0;
  1211. $scope.hasConditionTypes = 0;
  1212. $scope.hasUrlConditions = false;
  1213. $scope.isUrlConditionType = {
  1214. 'UrlWildcardCondition': true,
  1215. 'UrlRegexCondition': true
  1216. };
  1217. updateHasConditionTypes = function() {
  1218. var rule, _j, _k, _len1, _len2, _ref, _ref1, _ref2, _results;
  1219. if (((_ref = $scope.profile) != null ? _ref.rules : void 0) == null) {
  1220. return;
  1221. }
  1222. $scope.hasUrlConditions = false;
  1223. _ref1 = $scope.profile.rules;
  1224. for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
  1225. rule = _ref1[_j];
  1226. if ($scope.isUrlConditionType[rule.condition.conditionType]) {
  1227. $scope.hasUrlConditions = true;
  1228. break;
  1229. }
  1230. }
  1231. if ($scope.hasConditionTypes !== 0) {
  1232. return;
  1233. }
  1234. _ref2 = $scope.profile.rules;
  1235. _results = [];
  1236. for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
  1237. rule = _ref2[_k];
  1238. if (rule.condition.conditionType === 'TrueCondition') {
  1239. rule.condition = {
  1240. conditionType: 'HostWildcardCondition',
  1241. pattern: '*'
  1242. };
  1243. }
  1244. if (!basicConditionTypeSet[rule.condition.conditionType]) {
  1245. $scope.hasConditionTypes = 1;
  1246. $scope.showConditionTypes = 1;
  1247. break;
  1248. } else {
  1249. _results.push(void 0);
  1250. }
  1251. }
  1252. return _results;
  1253. };
  1254. $scope.$watch('options["-showConditionTypes"]', function(show) {
  1255. show || (show = 0);
  1256. if (show > 0) {
  1257. $scope.showConditionTypes = show;
  1258. } else {
  1259. updateHasConditionTypes();
  1260. $scope.showConditionTypes = $scope.hasConditionTypes;
  1261. }
  1262. if ($scope.options['-exportLegacyRuleList']) {
  1263. if ($scope.showConditionTypes > 0) {
  1264. $scope.setExportRuleListHandler(exportRuleList, {
  1265. warning: true
  1266. });
  1267. } else {
  1268. $scope.setExportRuleListHandler(exportLegacyRuleList);
  1269. }
  1270. } else {
  1271. $scope.setExportRuleListHandler(exportRuleList);
  1272. }
  1273. if ($scope.showConditionTypes === 0) {
  1274. $scope.conditionTypes = basicConditionTypesExpanded;
  1275. if ($scope.options['-exportLegacyRuleList']) {
  1276. return $scope.setExportRuleListHandler(exportLegacyRuleList);
  1277. }
  1278. } else {
  1279. $scope.conditionTypes = advancedConditionTypesExpanded;
  1280. if ($scope.options["-showConditionTypes"] == null) {
  1281. $scope.options["-showConditionTypes"] = $scope.showConditionTypes;
  1282. }
  1283. return typeof unwatchRules === "function" ? unwatchRules() : void 0;
  1284. }
  1285. });
  1286. if ($scope.hasConditionTypes === 0) {
  1287. unwatchRules = $scope.$watch('profile.rules', updateHasConditionTypes, true);
  1288. }
  1289. rulesReadyDefer = $q.defer();
  1290. rulesReady = rulesReadyDefer.promise;
  1291. stopWatchingForRules = $scope.$watch('profile.rules', function(rules) {
  1292. if (!rules) {
  1293. return;
  1294. }
  1295. stopWatchingForRules();
  1296. return rulesReadyDefer.resolve(rules);
  1297. });
  1298. $scope.addRule = function() {
  1299. var rule, templ, _ref;
  1300. rule = $scope.profile.rules.length > 0 ? ((_ref = $scope.profile.rules, templ = _ref[_ref.length - 1], _ref), angular.copy(templ)) : {
  1301. condition: {
  1302. conditionType: 'HostWildcardCondition',
  1303. pattern: ''
  1304. },
  1305. profileName: $scope.attachedOptions.defaultProfileName
  1306. };
  1307. if (rule.condition.pattern) {
  1308. rule.condition.pattern = '';
  1309. }
  1310. return $scope.profile.rules.push(rule);
  1311. };
  1312. $scope.validateCondition = function(condition, pattern) {
  1313. var _;
  1314. if (condition.conditionType.indexOf('Regex') >= 0) {
  1315. try {
  1316. new RegExp(pattern);
  1317. } catch (_error) {
  1318. _ = _error;
  1319. return false;
  1320. }
  1321. }
  1322. return true;
  1323. };
  1324. $scope.conditionHasWarning = function(condition) {
  1325. var pattern;
  1326. if (condition.conditionType === 'HostWildcardCondition') {
  1327. pattern = condition.pattern;
  1328. return pattern.indexOf(':') >= 0 || pattern.indexOf('/') >= 0;
  1329. }
  1330. return false;
  1331. };
  1332. $scope.validateIpCondition = function(condition, input) {
  1333. var ip;
  1334. if (!input) {
  1335. return false;
  1336. }
  1337. ip = OmegaPac.Conditions.parseIp(input);
  1338. return ip != null;
  1339. };
  1340. $scope.getWeekdayList = OmegaPac.Conditions.getWeekdayList;
  1341. $scope.updateDay = function(condition, i, selected) {
  1342. var char;
  1343. condition.days || (condition.days = '-------');
  1344. char = selected ? 'SMTWtFs'[i] : '-';
  1345. condition.days = condition.days.substr(0, i) + char + condition.days.substr(i + 1);
  1346. delete condition.startDay;
  1347. return delete condition.endDay;
  1348. };
  1349. $scope.removeRule = function(index) {
  1350. var removeForReal, scope;
  1351. removeForReal = function() {
  1352. return $scope.profile.rules.splice(index, 1);
  1353. };
  1354. if ($scope.options['-confirmDeletion']) {
  1355. scope = $scope.$new('isolate');
  1356. scope.rule = $scope.profile.rules[index];
  1357. scope.ruleProfile = $scope.profileByName(scope.rule.profileName);
  1358. scope.dispNameFilter = $scope.dispNameFilter;
  1359. scope.options = $scope.options;
  1360. return $modal.open({
  1361. templateUrl: 'partials/rule_remove_confirm.html',
  1362. scope: scope
  1363. }).result.then(removeForReal);
  1364. } else {
  1365. return removeForReal();
  1366. }
  1367. };
  1368. $scope.cloneRule = function(index) {
  1369. var rule;
  1370. rule = angular.copy($scope.profile.rules[index]);
  1371. $scope.profile.rules.splice(index + 1, 0, rule);
  1372. return $timeout(function() {
  1373. var input, _ref, _ref1;
  1374. input = angular.element(".switch-rule-row:nth-child(" + (index + 2) + ") input");
  1375. if ((_ref = input[0]) != null) {
  1376. _ref.focus();
  1377. }
  1378. return (_ref1 = input[0]) != null ? _ref1.select() : void 0;
  1379. });
  1380. };
  1381. $scope.showNotes = false;
  1382. $scope.addNote = function(index) {
  1383. $scope.showNotes = true;
  1384. return unwatchRulesShowNote();
  1385. };
  1386. unwatchRulesShowNote = $scope.$watch('profile.rules', (function(rules) {
  1387. if (rules && rules.some(function(rule) {
  1388. return !!rule.note;
  1389. })) {
  1390. $scope.showNotes = true;
  1391. return unwatchRulesShowNote();
  1392. }
  1393. }), true);
  1394. $scope.resetRules = function() {
  1395. var scope;
  1396. scope = $scope.$new('isolate');
  1397. scope.ruleProfile = $scope.profileByName($scope.attachedOptions.defaultProfileName);
  1398. scope.dispNameFilter = $scope.dispNameFilter;
  1399. scope.options = $scope.options;
  1400. return $modal.open({
  1401. templateUrl: 'partials/rule_reset_confirm.html',
  1402. scope: scope
  1403. }).result.then(function() {
  1404. var rule, _j, _len1, _ref, _results;
  1405. _ref = $scope.profile.rules;
  1406. _results = [];
  1407. for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
  1408. rule = _ref[_j];
  1409. _results.push(rule.profileName = $scope.attachedOptions.defaultProfileName);
  1410. }
  1411. return _results;
  1412. });
  1413. };
  1414. $scope.sortableOptions = {
  1415. handle: '.sort-bar',
  1416. tolerance: 'pointer',
  1417. axis: 'y',
  1418. forceHelperSize: true,
  1419. forcePlaceholderSize: true,
  1420. containment: 'parent'
  1421. };
  1422. attachedReadyDefer = $q.defer();
  1423. attachedReady = attachedReadyDefer.promise;
  1424. $scope.$watch('profile.name', function(name) {
  1425. $scope.attachedName = getAttachedName(name);
  1426. return $scope.attachedKey = OmegaPac.Profiles.nameAsKey($scope.attachedName);
  1427. });
  1428. $scope.$watch('options[attachedKey]', function(attached) {
  1429. return $scope.attached = attached;
  1430. });
  1431. $scope.watchAndUpdateRevision('options[attachedKey]');
  1432. oldSourceUrl = null;
  1433. oldLastUpdate = null;
  1434. oldRuleList = null;
  1435. onAttachedChange = function(attached, oldAttached) {
  1436. if (!(attached && oldAttached)) {
  1437. return;
  1438. }
  1439. if (attached.sourceUrl !== oldAttached.sourceUrl) {
  1440. if (attached.lastUpdate) {
  1441. oldSourceUrl = oldAttached.sourceUrl;
  1442. oldLastUpdate = attached.lastUpdate;
  1443. oldRuleList = oldAttached.ruleList;
  1444. return attached.lastUpdate = null;
  1445. } else if (oldSourceUrl && attached.sourceUrl === oldSourceUrl) {
  1446. attached.lastUpdate = oldLastUpdate;
  1447. return attached.ruleList = oldRuleList;
  1448. }
  1449. }
  1450. };
  1451. $scope.$watch('options[attachedKey]', onAttachedChange, true);
  1452. $scope.attachedOptions = {
  1453. enabled: false
  1454. };
  1455. $scope.$watch('profile.defaultProfileName', function(name) {
  1456. $scope.attachedOptions.enabled = name === $scope.attachedName;
  1457. if (!$scope.attached || !$scope.attachedOptions.enabled) {
  1458. return $scope.attachedOptions.defaultProfileName = name;
  1459. }
  1460. });
  1461. $scope.$watch('attachedOptions.enabled', function(enabled, oldValue) {
  1462. if (enabled === oldValue) {
  1463. return;
  1464. }
  1465. if (enabled) {
  1466. if ($scope.profile.defaultProfileName !== $scope.attachedName) {
  1467. return $scope.profile.defaultProfileName = $scope.attachedName;
  1468. }
  1469. } else {
  1470. if ($scope.profile.defaultProfileName === $scope.attachedName) {
  1471. if ($scope.attached) {
  1472. $scope.profile.defaultProfileName = $scope.attached.defaultProfileName;
  1473. return $scope.attachedOptions.defaultProfileName = $scope.attached.defaultProfileName;
  1474. } else {
  1475. $scope.profile.defaultProfileName = 'direct';
  1476. return $scope.attachedOptions.defaultProfileName = 'direct';
  1477. }
  1478. }
  1479. }
  1480. });
  1481. $scope.$watch('attached.defaultProfileName', function(name) {
  1482. if (name && $scope.attachedOptions.enabled) {
  1483. return $scope.attachedOptions.defaultProfileName = name;
  1484. }
  1485. });
  1486. $scope.$watch('attachedOptions.defaultProfileName', function(name) {
  1487. attachedReadyDefer.resolve();
  1488. if ($scope.attached && $scope.attachedOptions.enabled) {
  1489. return $scope.attached.defaultProfileName = name;
  1490. } else {
  1491. return $scope.profile.defaultProfileName = name;
  1492. }
  1493. });
  1494. $scope.attachNew = function() {
  1495. $scope.attached = OmegaPac.Profiles.create({
  1496. name: $scope.attachedName,
  1497. defaultProfileName: $scope.profile.defaultProfileName,
  1498. profileType: 'RuleListProfile',
  1499. color: $scope.profile.color
  1500. });
  1501. OmegaPac.Profiles.updateRevision($scope.attached);
  1502. $scope.options[$scope.attachedKey] = $scope.attached;
  1503. $scope.attachedOptions.enabled = true;
  1504. return $scope.profile.defaultProfileName = $scope.attachedName;
  1505. };
  1506. $scope.removeAttached = function() {
  1507. var scope;
  1508. if (!$scope.attached) {
  1509. return;
  1510. }
  1511. scope = $scope.$new('isolate');
  1512. scope.attached = $scope.attached;
  1513. scope.dispNameFilter = $scope.dispNameFilter;
  1514. scope.options = $scope.options;
  1515. return $modal.open({
  1516. templateUrl: 'partials/delete_attached.html',
  1517. scope: scope
  1518. }).result.then(function() {
  1519. $scope.profile.defaultProfileName = $scope.attached.defaultProfileName;
  1520. return delete $scope.options[$scope.attachedKey];
  1521. });
  1522. };
  1523. stateEditorKey = 'web._profileEditor.' + $scope.profile.name;
  1524. $scope.loadRules = false;
  1525. $scope.editSource = false;
  1526. parseOmegaRules = function(code, _arg) {
  1527. var detect, err, key, name, refs, requireResult, setError, _ref;
  1528. _ref = _arg != null ? _arg : {}, detect = _ref.detect, requireResult = _ref.requireResult;
  1529. setError = function(error) {
  1530. var args, message, _ref1;
  1531. if (error.reason) {
  1532. args = (_ref1 = error.args) != null ? _ref1 : [error.sourceLineNo, error.source];
  1533. message = trFilter('ruleList_error_' + error.reason, args);
  1534. if (message) {
  1535. error.message = message;
  1536. }
  1537. }
  1538. return {
  1539. error: error
  1540. };
  1541. };
  1542. if (detect && !OmegaPac.RuleList.Switchy.detect(code)) {
  1543. return {
  1544. error: {
  1545. reason: 'notSwitchy'
  1546. }
  1547. };
  1548. }
  1549. refs = OmegaPac.RuleList.Switchy.directReferenceSet({
  1550. ruleList: code
  1551. });
  1552. if (requireResult && !refs) {
  1553. return setError({
  1554. reason: 'resultNotEnabled'
  1555. });
  1556. }
  1557. for (key in refs) {
  1558. if (!__hasProp.call(refs, key)) continue;
  1559. name = refs[key];
  1560. if (!OmegaPac.Profiles.byKey(key, $scope.options)) {
  1561. return setError({
  1562. reason: 'unknownProfile',
  1563. args: [name]
  1564. });
  1565. }
  1566. }
  1567. try {
  1568. return {
  1569. rules: OmegaPac.RuleList.Switchy.parseOmega(code, null, null, {
  1570. strict: true,
  1571. source: false
  1572. })
  1573. };
  1574. } catch (_error) {
  1575. err = _error;
  1576. return setError(err);
  1577. }
  1578. };
  1579. parseSource = function() {
  1580. var diff, error, oldRules, patch, rules, _ref;
  1581. if (!$scope.source) {
  1582. return true;
  1583. }
  1584. _ref = parseOmegaRules($scope.source.code.trim(), {
  1585. requireResult: true
  1586. }), rules = _ref.rules, error = _ref.error;
  1587. if (error) {
  1588. $scope.source.error = error;
  1589. $scope.editSource = true;
  1590. return false;
  1591. } else {
  1592. $scope.source.error = void 0;
  1593. }
  1594. $scope.attachedOptions.defaultProfileName = rules.pop().profileName;
  1595. diff = jsondiffpatch.create({
  1596. objectHash: function(obj) {
  1597. return JSON.stringify(obj);
  1598. },
  1599. textDiff: {
  1600. minLength: 1 / 0
  1601. }
  1602. });
  1603. oldRules = angular.fromJson(angular.toJson($scope.profile.rules));
  1604. patch = diff.diff(oldRules, rules);
  1605. jsondiffpatch.patch($scope.profile.rules, patch);
  1606. return true;
  1607. };
  1608. $scope.toggleSource = function() {
  1609. return $q.all([attachedReady, rulesReady]).then(function() {
  1610. var args, code;
  1611. $scope.editSource = !$scope.editSource;
  1612. if ($scope.editSource) {
  1613. args = {
  1614. rules: $scope.profile.rules,
  1615. defaultProfileName: $scope.attachedOptions.defaultProfileName
  1616. };
  1617. code = OmegaPac.RuleList.Switchy.compose(args, {
  1618. withResult: true
  1619. });
  1620. $scope.source = {
  1621. code: code
  1622. };
  1623. } else {
  1624. if (!parseSource()) {
  1625. return;
  1626. }
  1627. $scope.source = null;
  1628. $scope.loadRules = true;
  1629. }
  1630. return omegaTarget.state(stateEditorKey, {
  1631. editSource: $scope.editSource
  1632. });
  1633. });
  1634. };
  1635. $rootScope.$on('$stateChangeStart', function(event, _, __, fromState) {
  1636. var sourceValid;
  1637. if ($scope.editSource && $scope.source.touched) {
  1638. sourceValid = parseSource();
  1639. if (!sourceValid) {
  1640. return event.preventDefault();
  1641. }
  1642. }
  1643. });
  1644. $scope.$on('omegaApplyOptions', function(event) {
  1645. var error, _ref;
  1646. if (((_ref = $scope.attached) != null ? _ref.ruleList : void 0) && !$scope.attached.sourceUrl) {
  1647. $scope.attachedRuleListError = void 0;
  1648. error = parseOmegaRules($scope.attached.ruleList.trim(), {
  1649. detect: true
  1650. }).error;
  1651. if (error) {
  1652. if (error.reason !== 'resultNotEnabled' && error.reason !== 'notSwitchy') {
  1653. $scope.attachedRuleListError = error;
  1654. event.preventDefault();
  1655. angular.element('#attached-rulelist')[0].focus();
  1656. }
  1657. } else {
  1658. $scope.attached.format = 'Switchy';
  1659. }
  1660. }
  1661. if ($scope.editSource && $scope.source.touched) {
  1662. event.preventDefault();
  1663. if (parseSource()) {
  1664. $scope.source.touched = false;
  1665. return $timeout(function() {
  1666. return $rootScope.applyOptions();
  1667. });
  1668. }
  1669. }
  1670. });
  1671. return omegaTarget.state(stateEditorKey).then(function(opts) {
  1672. var getState;
  1673. if (opts != null ? opts.editSource : void 0) {
  1674. return $scope.toggleSource();
  1675. } else {
  1676. $scope.loadRules = true;
  1677. getState = omegaTarget.state(['web.switchGuide', 'firstRun']);
  1678. return $q.all([rulesReady, getState]).then(function(_arg) {
  1679. var firstRun, switchGuide, _, _ref;
  1680. _ = _arg[0], (_ref = _arg[1], switchGuide = _ref[0], firstRun = _ref[1]);
  1681. if (firstRun || switchGuide === 'shown') {
  1682. return;
  1683. }
  1684. omegaTarget.state('web.switchGuide', 'shown');
  1685. if ($scope.profile.rules.length === 0) {
  1686. return;
  1687. }
  1688. return $script('js/switch_profile_guide.js');
  1689. });
  1690. }
  1691. });
  1692. });
  1693. }).call(this);
  1694. (function() {
  1695. angular.module('omega').directive('inputGroupClear', function($timeout) {
  1696. return {
  1697. restrict: 'A',
  1698. templateUrl: 'partials/input_group_clear.html',
  1699. scope: {
  1700. 'model': '=model',
  1701. 'type': '@type',
  1702. 'ngPattern': '=?ngPattern',
  1703. 'placeholder': '@placeholder',
  1704. 'controller': '=?controller'
  1705. },
  1706. link: function(scope, element, attrs) {
  1707. scope.catchAll = new RegExp('');
  1708. $timeout(function() {
  1709. return scope.controller = element.find('input').controller('ngModel');
  1710. });
  1711. scope.oldModel = '';
  1712. scope.controller = scope.input;
  1713. scope.modelChange = function() {
  1714. if (scope.model) {
  1715. return scope.oldModel = '';
  1716. }
  1717. };
  1718. return scope.toggleClear = function() {
  1719. var _ref;
  1720. return _ref = [scope.oldModel, scope.model], scope.model = _ref[0], scope.oldModel = _ref[1], _ref;
  1721. };
  1722. }
  1723. };
  1724. });
  1725. angular.module('omega').directive('omegaUpload', function() {
  1726. return {
  1727. restrict: 'A',
  1728. scope: {
  1729. success: '&omegaUpload',
  1730. error: '&omegaError'
  1731. },
  1732. link: function(scope, element, attrs) {
  1733. var input;
  1734. input = element[0];
  1735. return element.on('change', function() {
  1736. var reader;
  1737. if (input.files.length > 0 && input.files[0].name.length > 0) {
  1738. reader = new FileReader();
  1739. reader.addEventListener('load', function(e) {
  1740. return scope.$apply(function() {
  1741. return scope.success({
  1742. '$content': e.target.result
  1743. });
  1744. });
  1745. });
  1746. reader.addEventListener('error', function(e) {
  1747. return scope.$apply(function() {
  1748. return scope.error({
  1749. '$error': e.target.error
  1750. });
  1751. });
  1752. });
  1753. reader.readAsText(input.files[0]);
  1754. return input.value = '';
  1755. }
  1756. });
  1757. }
  1758. };
  1759. });
  1760. angular.module('omega').directive('omegaIp2str', function() {
  1761. return {
  1762. restrict: 'A',
  1763. priority: 2,
  1764. require: 'ngModel',
  1765. link: function(scope, element, attr, ngModel) {
  1766. ngModel.$parsers.push(function(value) {
  1767. if (value) {
  1768. return OmegaPac.Conditions.fromStr('Ip: ' + value);
  1769. } else {
  1770. return {
  1771. conditionType: 'IpCondition',
  1772. ip: '0.0.0.0',
  1773. prefixLength: 0
  1774. };
  1775. }
  1776. });
  1777. return ngModel.$formatters.push(function(value) {
  1778. if (value != null ? value.ip : void 0) {
  1779. return OmegaPac.Conditions.str(value).split(' ', 2)[1];
  1780. } else {
  1781. return '';
  1782. }
  1783. });
  1784. }
  1785. };
  1786. });
  1787. }).call(this);
  1788. (function() {
  1789. angular.module('omega').filter('profiles', function(builtinProfiles, profileOrder, isProfileNameHidden, isProfileNameReserved) {
  1790. var builtinProfileList, charCodePlus, profile, _;
  1791. charCodePlus = '+'.charCodeAt(0);
  1792. builtinProfileList = (function() {
  1793. var _results;
  1794. _results = [];
  1795. for (_ in builtinProfiles) {
  1796. profile = builtinProfiles[_];
  1797. _results.push(profile);
  1798. }
  1799. return _results;
  1800. })();
  1801. return function(options, filter) {
  1802. var name, result, value;
  1803. result = [];
  1804. for (name in options) {
  1805. value = options[name];
  1806. if (name.charCodeAt(0) === charCodePlus) {
  1807. result.push(value);
  1808. }
  1809. }
  1810. if (typeof filter === 'object' || (typeof filter === 'string' && filter.charCodeAt(0) === charCodePlus)) {
  1811. if (typeof filter === 'string') {
  1812. filter = filter.substr(1);
  1813. }
  1814. result = OmegaPac.Profiles.validResultProfilesFor(filter, options);
  1815. }
  1816. if (filter === 'all') {
  1817. result = result.filter(function(profile) {
  1818. return !isProfileNameHidden(profile.name);
  1819. });
  1820. result = result.concat(builtinProfileList);
  1821. } else {
  1822. result = result.filter(function(profile) {
  1823. return !isProfileNameReserved(profile.name);
  1824. });
  1825. }
  1826. if (filter === 'sorted') {
  1827. result.sort(profileOrder);
  1828. }
  1829. return result;
  1830. };
  1831. });
  1832. angular.module('omega').filter('tr', function(omegaTarget) {
  1833. return omegaTarget.getMessage;
  1834. });
  1835. angular.module('omega').filter('dispName', function(omegaTarget) {
  1836. return function(name) {
  1837. if (typeof name === 'object') {
  1838. name = name.name;
  1839. }
  1840. return omegaTarget.getMessage('profile_' + name) || name;
  1841. };
  1842. });
  1843. }).call(this);