virtualenv.py 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246
  1. #!/usr/bin/env python
  2. """Create a "virtual" Python installation
  3. """
  4. # If you change the version here, change it in setup.py
  5. # and docs/conf.py as well.
  6. virtualenv_version = "1.7"
  7. import base64
  8. import sys
  9. import os
  10. import optparse
  11. import re
  12. import shutil
  13. import logging
  14. import tempfile
  15. import zlib
  16. import errno
  17. import distutils.sysconfig
  18. from distutils.util import strtobool
  19. try:
  20. import subprocess
  21. except ImportError:
  22. if sys.version_info <= (2, 3):
  23. print('ERROR: %s' % sys.exc_info()[1])
  24. print('ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.')
  25. print('If you copy subprocess.py from a newer version of Python this script will probably work')
  26. sys.exit(101)
  27. else:
  28. raise
  29. try:
  30. set
  31. except NameError:
  32. from sets import Set as set
  33. try:
  34. basestring
  35. except NameError:
  36. basestring = str
  37. try:
  38. import ConfigParser
  39. except ImportError:
  40. import configparser as ConfigParser
  41. join = os.path.join
  42. py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
  43. is_jython = sys.platform.startswith('java')
  44. is_pypy = hasattr(sys, 'pypy_version_info')
  45. is_win = (sys.platform == 'win32')
  46. abiflags = getattr(sys, 'abiflags', '')
  47. user_dir = os.path.expanduser('~')
  48. if sys.platform == 'win32':
  49. user_dir = os.environ.get('APPDATA', user_dir) # Use %APPDATA% for roaming
  50. default_storage_dir = os.path.join(user_dir, 'virtualenv')
  51. else:
  52. default_storage_dir = os.path.join(user_dir, '.virtualenv')
  53. default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
  54. if is_pypy:
  55. expected_exe = 'pypy'
  56. elif is_jython:
  57. expected_exe = 'jython'
  58. else:
  59. expected_exe = 'python'
  60. REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
  61. 'fnmatch', 'locale', 'encodings', 'codecs',
  62. 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
  63. 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
  64. 'zlib']
  65. REQUIRED_FILES = ['lib-dynload', 'config']
  66. majver, minver = sys.version_info[:2]
  67. if majver == 2:
  68. if minver >= 6:
  69. REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
  70. if minver >= 7:
  71. REQUIRED_MODULES.extend(['_weakrefset'])
  72. if minver <= 3:
  73. REQUIRED_MODULES.extend(['sets', '__future__'])
  74. elif majver == 3:
  75. # Some extra modules are needed for Python 3, but different ones
  76. # for different versions.
  77. REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io',
  78. '_weakrefset', 'copyreg', 'tempfile', 'random',
  79. '__future__', 'collections', 'keyword', 'tarfile',
  80. 'shutil', 'struct', 'copy'])
  81. if minver >= 2:
  82. REQUIRED_FILES[-1] = 'config-%s' % majver
  83. if minver == 3:
  84. # The whole list of 3.3 modules is reproduced below - the current
  85. # uncommented ones are required for 3.3 as of now, but more may be
  86. # added as 3.3 development continues.
  87. REQUIRED_MODULES.extend([
  88. #"aifc",
  89. #"antigravity",
  90. #"argparse",
  91. #"ast",
  92. #"asynchat",
  93. #"asyncore",
  94. "base64",
  95. #"bdb",
  96. #"binhex",
  97. "bisect",
  98. #"calendar",
  99. #"cgi",
  100. #"cgitb",
  101. #"chunk",
  102. #"cmd",
  103. #"codeop",
  104. #"code",
  105. #"colorsys",
  106. #"_compat_pickle",
  107. #"compileall",
  108. #"concurrent",
  109. #"configparser",
  110. #"contextlib",
  111. #"cProfile",
  112. #"crypt",
  113. #"csv",
  114. #"ctypes",
  115. #"curses",
  116. #"datetime",
  117. #"dbm",
  118. #"decimal",
  119. #"difflib",
  120. #"dis",
  121. #"doctest",
  122. #"dummy_threading",
  123. "_dummy_thread",
  124. #"email",
  125. #"filecmp",
  126. #"fileinput",
  127. #"formatter",
  128. #"fractions",
  129. #"ftplib",
  130. #"functools",
  131. #"getopt",
  132. #"getpass",
  133. #"gettext",
  134. #"glob",
  135. #"gzip",
  136. "hashlib",
  137. "heapq",
  138. "hmac",
  139. #"html",
  140. #"http",
  141. #"idlelib",
  142. #"imaplib",
  143. #"imghdr",
  144. #"importlib",
  145. #"inspect",
  146. #"json",
  147. #"lib2to3",
  148. #"logging",
  149. #"macpath",
  150. #"macurl2path",
  151. #"mailbox",
  152. #"mailcap",
  153. #"_markupbase",
  154. #"mimetypes",
  155. #"modulefinder",
  156. #"multiprocessing",
  157. #"netrc",
  158. #"nntplib",
  159. #"nturl2path",
  160. #"numbers",
  161. #"opcode",
  162. #"optparse",
  163. #"os2emxpath",
  164. #"pdb",
  165. #"pickle",
  166. #"pickletools",
  167. #"pipes",
  168. #"pkgutil",
  169. #"platform",
  170. #"plat-linux2",
  171. #"plistlib",
  172. #"poplib",
  173. #"pprint",
  174. #"profile",
  175. #"pstats",
  176. #"pty",
  177. #"pyclbr",
  178. #"py_compile",
  179. #"pydoc_data",
  180. #"pydoc",
  181. #"_pyio",
  182. #"queue",
  183. #"quopri",
  184. "reprlib",
  185. "rlcompleter",
  186. #"runpy",
  187. #"sched",
  188. #"shelve",
  189. #"shlex",
  190. #"smtpd",
  191. #"smtplib",
  192. #"sndhdr",
  193. #"socket",
  194. #"socketserver",
  195. #"sqlite3",
  196. #"ssl",
  197. #"stringprep",
  198. #"string",
  199. #"_strptime",
  200. #"subprocess",
  201. #"sunau",
  202. #"symbol",
  203. #"symtable",
  204. #"sysconfig",
  205. #"tabnanny",
  206. #"telnetlib",
  207. #"test",
  208. #"textwrap",
  209. #"this",
  210. #"_threading_local",
  211. #"threading",
  212. #"timeit",
  213. #"tkinter",
  214. #"tokenize",
  215. #"token",
  216. #"traceback",
  217. #"trace",
  218. #"tty",
  219. #"turtledemo",
  220. #"turtle",
  221. #"unittest",
  222. #"urllib",
  223. #"uuid",
  224. #"uu",
  225. #"wave",
  226. "weakref",
  227. #"webbrowser",
  228. #"wsgiref",
  229. #"xdrlib",
  230. #"xml",
  231. #"xmlrpc",
  232. #"zipfile",
  233. ])
  234. if is_pypy:
  235. # these are needed to correctly display the exceptions that may happen
  236. # during the bootstrap
  237. REQUIRED_MODULES.extend(['traceback', 'linecache'])
  238. class Logger(object):
  239. """
  240. Logging object for use in command-line script. Allows ranges of
  241. levels, to avoid some redundancy of displayed information.
  242. """
  243. DEBUG = logging.DEBUG
  244. INFO = logging.INFO
  245. NOTIFY = (logging.INFO+logging.WARN)/2
  246. WARN = WARNING = logging.WARN
  247. ERROR = logging.ERROR
  248. FATAL = logging.FATAL
  249. LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
  250. def __init__(self, consumers):
  251. self.consumers = consumers
  252. self.indent = 0
  253. self.in_progress = None
  254. self.in_progress_hanging = False
  255. def debug(self, msg, *args, **kw):
  256. self.log(self.DEBUG, msg, *args, **kw)
  257. def info(self, msg, *args, **kw):
  258. self.log(self.INFO, msg, *args, **kw)
  259. def notify(self, msg, *args, **kw):
  260. self.log(self.NOTIFY, msg, *args, **kw)
  261. def warn(self, msg, *args, **kw):
  262. self.log(self.WARN, msg, *args, **kw)
  263. def error(self, msg, *args, **kw):
  264. self.log(self.WARN, msg, *args, **kw)
  265. def fatal(self, msg, *args, **kw):
  266. self.log(self.FATAL, msg, *args, **kw)
  267. def log(self, level, msg, *args, **kw):
  268. if args:
  269. if kw:
  270. raise TypeError(
  271. "You may give positional or keyword arguments, not both")
  272. args = args or kw
  273. rendered = None
  274. for consumer_level, consumer in self.consumers:
  275. if self.level_matches(level, consumer_level):
  276. if (self.in_progress_hanging
  277. and consumer in (sys.stdout, sys.stderr)):
  278. self.in_progress_hanging = False
  279. sys.stdout.write('\n')
  280. sys.stdout.flush()
  281. if rendered is None:
  282. if args:
  283. rendered = msg % args
  284. else:
  285. rendered = msg
  286. rendered = ' '*self.indent + rendered
  287. if hasattr(consumer, 'write'):
  288. consumer.write(rendered+'\n')
  289. else:
  290. consumer(rendered)
  291. def start_progress(self, msg):
  292. assert not self.in_progress, (
  293. "Tried to start_progress(%r) while in_progress %r"
  294. % (msg, self.in_progress))
  295. if self.level_matches(self.NOTIFY, self._stdout_level()):
  296. sys.stdout.write(msg)
  297. sys.stdout.flush()
  298. self.in_progress_hanging = True
  299. else:
  300. self.in_progress_hanging = False
  301. self.in_progress = msg
  302. def end_progress(self, msg='done.'):
  303. assert self.in_progress, (
  304. "Tried to end_progress without start_progress")
  305. if self.stdout_level_matches(self.NOTIFY):
  306. if not self.in_progress_hanging:
  307. # Some message has been printed out since start_progress
  308. sys.stdout.write('...' + self.in_progress + msg + '\n')
  309. sys.stdout.flush()
  310. else:
  311. sys.stdout.write(msg + '\n')
  312. sys.stdout.flush()
  313. self.in_progress = None
  314. self.in_progress_hanging = False
  315. def show_progress(self):
  316. """If we are in a progress scope, and no log messages have been
  317. shown, write out another '.'"""
  318. if self.in_progress_hanging:
  319. sys.stdout.write('.')
  320. sys.stdout.flush()
  321. def stdout_level_matches(self, level):
  322. """Returns true if a message at this level will go to stdout"""
  323. return self.level_matches(level, self._stdout_level())
  324. def _stdout_level(self):
  325. """Returns the level that stdout runs at"""
  326. for level, consumer in self.consumers:
  327. if consumer is sys.stdout:
  328. return level
  329. return self.FATAL
  330. def level_matches(self, level, consumer_level):
  331. """
  332. >>> l = Logger([])
  333. >>> l.level_matches(3, 4)
  334. False
  335. >>> l.level_matches(3, 2)
  336. True
  337. >>> l.level_matches(slice(None, 3), 3)
  338. False
  339. >>> l.level_matches(slice(None, 3), 2)
  340. True
  341. >>> l.level_matches(slice(1, 3), 1)
  342. True
  343. >>> l.level_matches(slice(2, 3), 1)
  344. False
  345. """
  346. if isinstance(level, slice):
  347. start, stop = level.start, level.stop
  348. if start is not None and start > consumer_level:
  349. return False
  350. if stop is not None and stop <= consumer_level:
  351. return False
  352. return True
  353. else:
  354. return level >= consumer_level
  355. #@classmethod
  356. def level_for_integer(cls, level):
  357. levels = cls.LEVELS
  358. if level < 0:
  359. return levels[0]
  360. if level >= len(levels):
  361. return levels[-1]
  362. return levels[level]
  363. level_for_integer = classmethod(level_for_integer)
  364. # create a silent logger just to prevent this from being undefined
  365. # will be overridden with requested verbosity main() is called.
  366. logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
  367. def mkdir(path):
  368. if not os.path.exists(path):
  369. logger.info('Creating %s', path)
  370. os.makedirs(path)
  371. else:
  372. logger.info('Directory %s already exists', path)
  373. def copyfileordir(src, dest):
  374. if os.path.isdir(src):
  375. shutil.copytree(src, dest, True)
  376. else:
  377. shutil.copy2(src, dest)
  378. def copyfile(src, dest, symlink=True):
  379. if not os.path.exists(src):
  380. # Some bad symlink in the src
  381. logger.warn('Cannot find file %s (bad symlink)', src)
  382. return
  383. if os.path.exists(dest):
  384. logger.debug('File %s already exists', dest)
  385. return
  386. if not os.path.exists(os.path.dirname(dest)):
  387. logger.info('Creating parent directories for %s' % os.path.dirname(dest))
  388. os.makedirs(os.path.dirname(dest))
  389. if not os.path.islink(src):
  390. srcpath = os.path.abspath(src)
  391. else:
  392. srcpath = os.readlink(src)
  393. if symlink and hasattr(os, 'symlink') and not is_win:
  394. logger.info('Symlinking %s', dest)
  395. try:
  396. os.symlink(srcpath, dest)
  397. except (OSError, NotImplementedError):
  398. logger.info('Symlinking failed, copying to %s', dest)
  399. copyfileordir(src, dest)
  400. else:
  401. logger.info('Copying to %s', dest)
  402. copyfileordir(src, dest)
  403. def writefile(dest, content, overwrite=True):
  404. if not os.path.exists(dest):
  405. logger.info('Writing %s', dest)
  406. f = open(dest, 'wb')
  407. f.write(content.encode('utf-8'))
  408. f.close()
  409. return
  410. else:
  411. f = open(dest, 'rb')
  412. c = f.read()
  413. f.close()
  414. if c != content:
  415. if not overwrite:
  416. logger.notify('File %s exists with different content; not overwriting', dest)
  417. return
  418. logger.notify('Overwriting %s with new content', dest)
  419. f = open(dest, 'wb')
  420. f.write(content.encode('utf-8'))
  421. f.close()
  422. else:
  423. logger.info('Content %s already in place', dest)
  424. def rmtree(dir):
  425. if os.path.exists(dir):
  426. logger.notify('Deleting tree %s', dir)
  427. shutil.rmtree(dir)
  428. else:
  429. logger.info('Do not need to delete %s; already gone', dir)
  430. def make_exe(fn):
  431. if hasattr(os, 'chmod'):
  432. oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
  433. newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
  434. os.chmod(fn, newmode)
  435. logger.info('Changed mode of %s to %s', fn, oct(newmode))
  436. def _find_file(filename, dirs):
  437. for dir in reversed(dirs):
  438. if os.path.exists(join(dir, filename)):
  439. return join(dir, filename)
  440. return filename
  441. def _install_req(py_executable, unzip=False, distribute=False,
  442. search_dirs=None, never_download=False):
  443. if search_dirs is None:
  444. search_dirs = file_search_dirs()
  445. if not distribute:
  446. setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3]
  447. project_name = 'setuptools'
  448. bootstrap_script = EZ_SETUP_PY
  449. source = None
  450. else:
  451. setup_fn = None
  452. source = 'distribute-0.6.24.tar.gz'
  453. project_name = 'distribute'
  454. bootstrap_script = DISTRIBUTE_SETUP_PY
  455. if setup_fn is not None:
  456. setup_fn = _find_file(setup_fn, search_dirs)
  457. if source is not None:
  458. source = _find_file(source, search_dirs)
  459. if is_jython and os._name == 'nt':
  460. # Jython's .bat sys.executable can't handle a command line
  461. # argument with newlines
  462. fd, ez_setup = tempfile.mkstemp('.py')
  463. os.write(fd, bootstrap_script)
  464. os.close(fd)
  465. cmd = [py_executable, ez_setup]
  466. else:
  467. cmd = [py_executable, '-c', bootstrap_script]
  468. if unzip:
  469. cmd.append('--always-unzip')
  470. env = {}
  471. remove_from_env = []
  472. if logger.stdout_level_matches(logger.DEBUG):
  473. cmd.append('-v')
  474. old_chdir = os.getcwd()
  475. if setup_fn is not None and os.path.exists(setup_fn):
  476. logger.info('Using existing %s egg: %s' % (project_name, setup_fn))
  477. cmd.append(setup_fn)
  478. if os.environ.get('PYTHONPATH'):
  479. env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH']
  480. else:
  481. env['PYTHONPATH'] = setup_fn
  482. else:
  483. # the source is found, let's chdir
  484. if source is not None and os.path.exists(source):
  485. logger.info('Using existing %s egg: %s' % (project_name, source))
  486. os.chdir(os.path.dirname(source))
  487. # in this case, we want to be sure that PYTHONPATH is unset (not
  488. # just empty, really unset), else CPython tries to import the
  489. # site.py that it's in virtualenv_support
  490. remove_from_env.append('PYTHONPATH')
  491. else:
  492. if never_download:
  493. logger.fatal("Can't find any local distributions of %s to install "
  494. "and --never-download is set. Either re-run virtualenv "
  495. "without the --never-download option, or place a %s "
  496. "distribution (%s) in one of these "
  497. "locations: %r" % (project_name, project_name,
  498. setup_fn or source,
  499. search_dirs))
  500. sys.exit(1)
  501. logger.info('No %s egg found; downloading' % project_name)
  502. cmd.extend(['--always-copy', '-U', project_name])
  503. logger.start_progress('Installing %s...' % project_name)
  504. logger.indent += 2
  505. cwd = None
  506. if project_name == 'distribute':
  507. env['DONT_PATCH_SETUPTOOLS'] = 'true'
  508. def _filter_ez_setup(line):
  509. return filter_ez_setup(line, project_name)
  510. if not os.access(os.getcwd(), os.W_OK):
  511. cwd = tempfile.mkdtemp()
  512. if source is not None and os.path.exists(source):
  513. # the current working dir is hostile, let's copy the
  514. # tarball to a temp dir
  515. target = os.path.join(cwd, os.path.split(source)[-1])
  516. shutil.copy(source, target)
  517. try:
  518. call_subprocess(cmd, show_stdout=False,
  519. filter_stdout=_filter_ez_setup,
  520. extra_env=env,
  521. remove_from_env=remove_from_env,
  522. cwd=cwd)
  523. finally:
  524. logger.indent -= 2
  525. logger.end_progress()
  526. if os.getcwd() != old_chdir:
  527. os.chdir(old_chdir)
  528. if is_jython and os._name == 'nt':
  529. os.remove(ez_setup)
  530. def file_search_dirs():
  531. here = os.path.dirname(os.path.abspath(__file__))
  532. dirs = ['.', here,
  533. join(here, 'virtualenv_support')]
  534. if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
  535. # Probably some boot script; just in case virtualenv is installed...
  536. try:
  537. import virtualenv
  538. except ImportError:
  539. pass
  540. else:
  541. dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
  542. return [d for d in dirs if os.path.isdir(d)]
  543. def install_setuptools(py_executable, unzip=False,
  544. search_dirs=None, never_download=False):
  545. _install_req(py_executable, unzip,
  546. search_dirs=search_dirs, never_download=never_download)
  547. def install_distribute(py_executable, unzip=False,
  548. search_dirs=None, never_download=False):
  549. _install_req(py_executable, unzip, distribute=True,
  550. search_dirs=search_dirs, never_download=never_download)
  551. _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I)
  552. def install_pip(py_executable, search_dirs=None, never_download=False):
  553. if search_dirs is None:
  554. search_dirs = file_search_dirs()
  555. filenames = []
  556. for dir in search_dirs:
  557. filenames.extend([join(dir, fn) for fn in os.listdir(dir)
  558. if _pip_re.search(fn)])
  559. filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)]
  560. filenames.sort()
  561. filenames = [filename for basename, i, filename in filenames]
  562. if not filenames:
  563. filename = 'pip'
  564. else:
  565. filename = filenames[-1]
  566. easy_install_script = 'easy_install'
  567. if sys.platform == 'win32':
  568. easy_install_script = 'easy_install-script.py'
  569. cmd = [join(os.path.dirname(py_executable), easy_install_script), filename]
  570. if sys.platform == 'win32':
  571. cmd.insert(0, py_executable)
  572. if filename == 'pip':
  573. if never_download:
  574. logger.fatal("Can't find any local distributions of pip to install "
  575. "and --never-download is set. Either re-run virtualenv "
  576. "without the --never-download option, or place a pip "
  577. "source distribution (zip/tar.gz/tar.bz2) in one of these "
  578. "locations: %r" % search_dirs)
  579. sys.exit(1)
  580. logger.info('Installing pip from network...')
  581. else:
  582. logger.info('Installing existing %s distribution: %s' % (
  583. os.path.basename(filename), filename))
  584. logger.start_progress('Installing pip...')
  585. logger.indent += 2
  586. def _filter_setup(line):
  587. return filter_ez_setup(line, 'pip')
  588. try:
  589. call_subprocess(cmd, show_stdout=False,
  590. filter_stdout=_filter_setup)
  591. finally:
  592. logger.indent -= 2
  593. logger.end_progress()
  594. def filter_ez_setup(line, project_name='setuptools'):
  595. if not line.strip():
  596. return Logger.DEBUG
  597. if project_name == 'distribute':
  598. for prefix in ('Extracting', 'Now working', 'Installing', 'Before',
  599. 'Scanning', 'Setuptools', 'Egg', 'Already',
  600. 'running', 'writing', 'reading', 'installing',
  601. 'creating', 'copying', 'byte-compiling', 'removing',
  602. 'Processing'):
  603. if line.startswith(prefix):
  604. return Logger.DEBUG
  605. return Logger.DEBUG
  606. for prefix in ['Reading ', 'Best match', 'Processing setuptools',
  607. 'Copying setuptools', 'Adding setuptools',
  608. 'Installing ', 'Installed ']:
  609. if line.startswith(prefix):
  610. return Logger.DEBUG
  611. return Logger.INFO
  612. class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
  613. """
  614. Custom help formatter for use in ConfigOptionParser that updates
  615. the defaults before expanding them, allowing them to show up correctly
  616. in the help listing
  617. """
  618. def expand_default(self, option):
  619. if self.parser is not None:
  620. self.parser.update_defaults(self.parser.defaults)
  621. return optparse.IndentedHelpFormatter.expand_default(self, option)
  622. class ConfigOptionParser(optparse.OptionParser):
  623. """
  624. Custom option parser which updates its defaults by by checking the
  625. configuration files and environmental variables
  626. """
  627. def __init__(self, *args, **kwargs):
  628. self.config = ConfigParser.RawConfigParser()
  629. self.files = self.get_config_files()
  630. self.config.read(self.files)
  631. optparse.OptionParser.__init__(self, *args, **kwargs)
  632. def get_config_files(self):
  633. config_file = os.environ.get('VIRTUALENV_CONFIG_FILE', False)
  634. if config_file and os.path.exists(config_file):
  635. return [config_file]
  636. return [default_config_file]
  637. def update_defaults(self, defaults):
  638. """
  639. Updates the given defaults with values from the config files and
  640. the environ. Does a little special handling for certain types of
  641. options (lists).
  642. """
  643. # Then go and look for the other sources of configuration:
  644. config = {}
  645. # 1. config files
  646. config.update(dict(self.get_config_section('virtualenv')))
  647. # 2. environmental variables
  648. config.update(dict(self.get_environ_vars()))
  649. # Then set the options with those values
  650. for key, val in config.items():
  651. key = key.replace('_', '-')
  652. if not key.startswith('--'):
  653. key = '--%s' % key # only prefer long opts
  654. option = self.get_option(key)
  655. if option is not None:
  656. # ignore empty values
  657. if not val:
  658. continue
  659. # handle multiline configs
  660. if option.action == 'append':
  661. val = val.split()
  662. else:
  663. option.nargs = 1
  664. if option.action in ('store_true', 'store_false', 'count'):
  665. val = strtobool(val)
  666. try:
  667. val = option.convert_value(key, val)
  668. except optparse.OptionValueError:
  669. e = sys.exc_info()[1]
  670. print("An error occured during configuration: %s" % e)
  671. sys.exit(3)
  672. defaults[option.dest] = val
  673. return defaults
  674. def get_config_section(self, name):
  675. """
  676. Get a section of a configuration
  677. """
  678. if self.config.has_section(name):
  679. return self.config.items(name)
  680. return []
  681. def get_environ_vars(self, prefix='VIRTUALENV_'):
  682. """
  683. Returns a generator with all environmental vars with prefix VIRTUALENV
  684. """
  685. for key, val in os.environ.items():
  686. if key.startswith(prefix):
  687. yield (key.replace(prefix, '').lower(), val)
  688. def get_default_values(self):
  689. """
  690. Overridding to make updating the defaults after instantiation of
  691. the option parser possible, update_defaults() does the dirty work.
  692. """
  693. if not self.process_default_values:
  694. # Old, pre-Optik 1.5 behaviour.
  695. return optparse.Values(self.defaults)
  696. defaults = self.update_defaults(self.defaults.copy()) # ours
  697. for option in self._get_all_options():
  698. default = defaults.get(option.dest)
  699. if isinstance(default, basestring):
  700. opt_str = option.get_opt_string()
  701. defaults[option.dest] = option.check_value(opt_str, default)
  702. return optparse.Values(defaults)
  703. def main():
  704. parser = ConfigOptionParser(
  705. version=virtualenv_version,
  706. usage="%prog [OPTIONS] DEST_DIR",
  707. formatter=UpdatingDefaultsHelpFormatter())
  708. parser.add_option(
  709. '-v', '--verbose',
  710. action='count',
  711. dest='verbose',
  712. default=0,
  713. help="Increase verbosity")
  714. parser.add_option(
  715. '-q', '--quiet',
  716. action='count',
  717. dest='quiet',
  718. default=0,
  719. help='Decrease verbosity')
  720. parser.add_option(
  721. '-p', '--python',
  722. dest='python',
  723. metavar='PYTHON_EXE',
  724. help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
  725. 'interpreter to create the new environment. The default is the interpreter that '
  726. 'virtualenv was installed with (%s)' % sys.executable)
  727. parser.add_option(
  728. '--clear',
  729. dest='clear',
  730. action='store_true',
  731. help="Clear out the non-root install and start from scratch")
  732. parser.add_option(
  733. '--no-site-packages',
  734. dest='no_site_packages',
  735. action='store_true',
  736. help="Don't give access to the global site-packages dir to the "
  737. "virtual environment")
  738. parser.add_option(
  739. '--system-site-packages',
  740. dest='system_site_packages',
  741. action='store_true',
  742. help="Give access to the global site-packages dir to the "
  743. "virtual environment")
  744. parser.add_option(
  745. '--unzip-setuptools',
  746. dest='unzip_setuptools',
  747. action='store_true',
  748. help="Unzip Setuptools or Distribute when installing it")
  749. parser.add_option(
  750. '--relocatable',
  751. dest='relocatable',
  752. action='store_true',
  753. help='Make an EXISTING virtualenv environment relocatable. '
  754. 'This fixes up scripts and makes all .pth files relative')
  755. parser.add_option(
  756. '--distribute',
  757. dest='use_distribute',
  758. action='store_true',
  759. help='Use Distribute instead of Setuptools. Set environ variable '
  760. 'VIRTUALENV_DISTRIBUTE to make it the default ')
  761. default_search_dirs = file_search_dirs()
  762. parser.add_option(
  763. '--extra-search-dir',
  764. dest="search_dirs",
  765. action="append",
  766. default=default_search_dirs,
  767. help="Directory to look for setuptools/distribute/pip distributions in. "
  768. "You can add any number of additional --extra-search-dir paths.")
  769. parser.add_option(
  770. '--never-download',
  771. dest="never_download",
  772. action="store_true",
  773. help="Never download anything from the network. Instead, virtualenv will fail "
  774. "if local distributions of setuptools/distribute/pip are not present.")
  775. parser.add_option(
  776. '--prompt=',
  777. dest='prompt',
  778. help='Provides an alternative prompt prefix for this environment')
  779. if 'extend_parser' in globals():
  780. extend_parser(parser)
  781. options, args = parser.parse_args()
  782. global logger
  783. if 'adjust_options' in globals():
  784. adjust_options(options, args)
  785. verbosity = options.verbose - options.quiet
  786. logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)])
  787. if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
  788. env = os.environ.copy()
  789. interpreter = resolve_interpreter(options.python)
  790. if interpreter == sys.executable:
  791. logger.warn('Already using interpreter %s' % interpreter)
  792. else:
  793. logger.notify('Running virtualenv with interpreter %s' % interpreter)
  794. env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
  795. file = __file__
  796. if file.endswith('.pyc'):
  797. file = file[:-1]
  798. popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
  799. raise SystemExit(popen.wait())
  800. # Force --distribute on Python 3, since setuptools is not available.
  801. if majver > 2:
  802. options.use_distribute = True
  803. if os.environ.get('PYTHONDONTWRITEBYTECODE') and not options.use_distribute:
  804. print(
  805. "The PYTHONDONTWRITEBYTECODE environment variable is "
  806. "not compatible with setuptools. Either use --distribute "
  807. "or unset PYTHONDONTWRITEBYTECODE.")
  808. sys.exit(2)
  809. if not args:
  810. print('You must provide a DEST_DIR')
  811. parser.print_help()
  812. sys.exit(2)
  813. if len(args) > 1:
  814. print('There must be only one argument: DEST_DIR (you gave %s)' % (
  815. ' '.join(args)))
  816. parser.print_help()
  817. sys.exit(2)
  818. home_dir = args[0]
  819. if os.environ.get('WORKING_ENV'):
  820. logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
  821. logger.fatal('Please deactivate your workingenv, then re-run this script')
  822. sys.exit(3)
  823. if 'PYTHONHOME' in os.environ:
  824. logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
  825. del os.environ['PYTHONHOME']
  826. if options.relocatable:
  827. make_environment_relocatable(home_dir)
  828. return
  829. if options.no_site_packages:
  830. logger.warn('The --no-site-packages flag is deprecated; it is now '
  831. 'the default behavior.')
  832. create_environment(home_dir,
  833. site_packages=options.system_site_packages,
  834. clear=options.clear,
  835. unzip_setuptools=options.unzip_setuptools,
  836. use_distribute=options.use_distribute,
  837. prompt=options.prompt,
  838. search_dirs=options.search_dirs,
  839. never_download=options.never_download)
  840. if 'after_install' in globals():
  841. after_install(options, home_dir)
  842. def call_subprocess(cmd, show_stdout=True,
  843. filter_stdout=None, cwd=None,
  844. raise_on_returncode=True, extra_env=None,
  845. remove_from_env=None):
  846. cmd_parts = []
  847. for part in cmd:
  848. if len(part) > 45:
  849. part = part[:20]+"..."+part[-20:]
  850. if ' ' in part or '\n' in part or '"' in part or "'" in part:
  851. part = '"%s"' % part.replace('"', '\\"')
  852. if hasattr(part, 'decode'):
  853. try:
  854. part = part.decode(sys.getdefaultencoding())
  855. except UnicodeDecodeError:
  856. part = part.decode(sys.getfilesystemencoding())
  857. cmd_parts.append(part)
  858. cmd_desc = ' '.join(cmd_parts)
  859. if show_stdout:
  860. stdout = None
  861. else:
  862. stdout = subprocess.PIPE
  863. logger.debug("Running command %s" % cmd_desc)
  864. if extra_env or remove_from_env:
  865. env = os.environ.copy()
  866. if extra_env:
  867. env.update(extra_env)
  868. if remove_from_env:
  869. for varname in remove_from_env:
  870. env.pop(varname, None)
  871. else:
  872. env = None
  873. try:
  874. proc = subprocess.Popen(
  875. cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
  876. cwd=cwd, env=env)
  877. except Exception:
  878. e = sys.exc_info()[1]
  879. logger.fatal(
  880. "Error %s while executing command %s" % (e, cmd_desc))
  881. raise
  882. all_output = []
  883. if stdout is not None:
  884. stdout = proc.stdout
  885. encoding = sys.getdefaultencoding()
  886. fs_encoding = sys.getfilesystemencoding()
  887. while 1:
  888. line = stdout.readline()
  889. try:
  890. line = line.decode(encoding)
  891. except UnicodeDecodeError:
  892. line = line.decode(fs_encoding)
  893. if not line:
  894. break
  895. line = line.rstrip()
  896. all_output.append(line)
  897. if filter_stdout:
  898. level = filter_stdout(line)
  899. if isinstance(level, tuple):
  900. level, line = level
  901. logger.log(level, line)
  902. if not logger.stdout_level_matches(level):
  903. logger.show_progress()
  904. else:
  905. logger.info(line)
  906. else:
  907. proc.communicate()
  908. proc.wait()
  909. if proc.returncode:
  910. if raise_on_returncode:
  911. if all_output:
  912. logger.notify('Complete output from command %s:' % cmd_desc)
  913. logger.notify('\n'.join(all_output) + '\n----------------------------------------')
  914. raise OSError(
  915. "Command %s failed with error code %s"
  916. % (cmd_desc, proc.returncode))
  917. else:
  918. logger.warn(
  919. "Command %s had error code %s"
  920. % (cmd_desc, proc.returncode))
  921. def create_environment(home_dir, site_packages=False, clear=False,
  922. unzip_setuptools=False, use_distribute=False,
  923. prompt=None, search_dirs=None, never_download=False):
  924. """
  925. Creates a new environment in ``home_dir``.
  926. If ``site_packages`` is true, then the global ``site-packages/``
  927. directory will be on the path.
  928. If ``clear`` is true (default False) then the environment will
  929. first be cleared.
  930. """
  931. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  932. py_executable = os.path.abspath(install_python(
  933. home_dir, lib_dir, inc_dir, bin_dir,
  934. site_packages=site_packages, clear=clear))
  935. install_distutils(home_dir)
  936. # use_distribute also is True if VIRTUALENV_DISTRIBUTE env var is set
  937. # we also check VIRTUALENV_USE_DISTRIBUTE for backwards compatibility
  938. if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'):
  939. install_distribute(py_executable, unzip=unzip_setuptools,
  940. search_dirs=search_dirs, never_download=never_download)
  941. else:
  942. install_setuptools(py_executable, unzip=unzip_setuptools,
  943. search_dirs=search_dirs, never_download=never_download)
  944. install_pip(py_executable, search_dirs=search_dirs, never_download=never_download)
  945. install_activate(home_dir, bin_dir, prompt)
  946. def path_locations(home_dir):
  947. """Return the path locations for the environment (where libraries are,
  948. where scripts go, etc)"""
  949. # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  950. # prefix arg is broken: http://bugs.python.org/issue3386
  951. if sys.platform == 'win32':
  952. # Windows has lots of problems with executables with spaces in
  953. # the name; this function will remove them (using the ~1
  954. # format):
  955. mkdir(home_dir)
  956. if ' ' in home_dir:
  957. try:
  958. import win32api
  959. except ImportError:
  960. print('Error: the path "%s" has a space in it' % home_dir)
  961. print('To handle these kinds of paths, the win32api module must be installed:')
  962. print(' http://sourceforge.net/projects/pywin32/')
  963. sys.exit(3)
  964. home_dir = win32api.GetShortPathName(home_dir)
  965. lib_dir = join(home_dir, 'Lib')
  966. inc_dir = join(home_dir, 'Include')
  967. bin_dir = join(home_dir, 'Scripts')
  968. elif is_jython:
  969. lib_dir = join(home_dir, 'Lib')
  970. inc_dir = join(home_dir, 'Include')
  971. bin_dir = join(home_dir, 'bin')
  972. elif is_pypy:
  973. lib_dir = home_dir
  974. inc_dir = join(home_dir, 'include')
  975. bin_dir = join(home_dir, 'bin')
  976. else:
  977. lib_dir = join(home_dir, 'lib', py_version)
  978. inc_dir = join(home_dir, 'include', py_version + abiflags)
  979. bin_dir = join(home_dir, 'bin')
  980. return home_dir, lib_dir, inc_dir, bin_dir
  981. def change_prefix(filename, dst_prefix):
  982. prefixes = [sys.prefix]
  983. if sys.platform == "darwin":
  984. prefixes.extend((
  985. os.path.join("/Library/Python", sys.version[:3], "site-packages"),
  986. os.path.join(sys.prefix, "Extras", "lib", "python"),
  987. os.path.join("~", "Library", "Python", sys.version[:3], "site-packages")))
  988. if hasattr(sys, 'real_prefix'):
  989. prefixes.append(sys.real_prefix)
  990. prefixes = list(map(os.path.abspath, prefixes))
  991. filename = os.path.abspath(filename)
  992. for src_prefix in prefixes:
  993. if filename.startswith(src_prefix):
  994. _, relpath = filename.split(src_prefix, 1)
  995. assert relpath[0] == os.sep
  996. relpath = relpath[1:]
  997. return join(dst_prefix, relpath)
  998. assert False, "Filename %s does not start with any of these prefixes: %s" % \
  999. (filename, prefixes)
  1000. def copy_required_modules(dst_prefix):
  1001. import imp
  1002. # If we are running under -p, we need to remove the current
  1003. # directory from sys.path temporarily here, so that we
  1004. # definitely get the modules from the site directory of
  1005. # the interpreter we are running under, not the one
  1006. # virtualenv.py is installed under (which might lead to py2/py3
  1007. # incompatibility issues)
  1008. _prev_sys_path = sys.path
  1009. if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
  1010. sys.path = sys.path[1:]
  1011. try:
  1012. for modname in REQUIRED_MODULES:
  1013. if modname in sys.builtin_module_names:
  1014. logger.info("Ignoring built-in bootstrap module: %s" % modname)
  1015. continue
  1016. try:
  1017. f, filename, _ = imp.find_module(modname)
  1018. except ImportError:
  1019. logger.info("Cannot import bootstrap module: %s" % modname)
  1020. else:
  1021. if f is not None:
  1022. f.close()
  1023. dst_filename = change_prefix(filename, dst_prefix)
  1024. copyfile(filename, dst_filename)
  1025. if filename.endswith('.pyc'):
  1026. pyfile = filename[:-1]
  1027. if os.path.exists(pyfile):
  1028. copyfile(pyfile, dst_filename[:-1])
  1029. finally:
  1030. sys.path = _prev_sys_path
  1031. def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
  1032. """Install just the base environment, no distutils patches etc"""
  1033. if sys.executable.startswith(bin_dir):
  1034. print('Please use the *system* python to run this script')
  1035. return
  1036. if clear:
  1037. rmtree(lib_dir)
  1038. ## FIXME: why not delete it?
  1039. ## Maybe it should delete everything with #!/path/to/venv/python in it
  1040. logger.notify('Not deleting %s', bin_dir)
  1041. if hasattr(sys, 'real_prefix'):
  1042. logger.notify('Using real prefix %r' % sys.real_prefix)
  1043. prefix = sys.real_prefix
  1044. else:
  1045. prefix = sys.prefix
  1046. mkdir(lib_dir)
  1047. fix_lib64(lib_dir)
  1048. stdlib_dirs = [os.path.dirname(os.__file__)]
  1049. if sys.platform == 'win32':
  1050. stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  1051. elif sys.platform == 'darwin':
  1052. stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  1053. if hasattr(os, 'symlink'):
  1054. logger.info('Symlinking Python bootstrap modules')
  1055. else:
  1056. logger.info('Copying Python bootstrap modules')
  1057. logger.indent += 2
  1058. try:
  1059. # copy required files...
  1060. for stdlib_dir in stdlib_dirs:
  1061. if not os.path.isdir(stdlib_dir):
  1062. continue
  1063. for fn in os.listdir(stdlib_dir):
  1064. bn = os.path.splitext(fn)[0]
  1065. if fn != 'site-packages' and bn in REQUIRED_FILES:
  1066. copyfile(join(stdlib_dir, fn), join(lib_dir, fn))
  1067. # ...and modules
  1068. copy_required_modules(home_dir)
  1069. finally:
  1070. logger.indent -= 2
  1071. mkdir(join(lib_dir, 'site-packages'))
  1072. import site
  1073. site_filename = site.__file__
  1074. if site_filename.endswith('.pyc'):
  1075. site_filename = site_filename[:-1]
  1076. elif site_filename.endswith('$py.class'):
  1077. site_filename = site_filename.replace('$py.class', '.py')
  1078. site_filename_dst = change_prefix(site_filename, home_dir)
  1079. site_dir = os.path.dirname(site_filename_dst)
  1080. writefile(site_filename_dst, SITE_PY)
  1081. writefile(join(site_dir, 'orig-prefix.txt'), prefix)
  1082. site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
  1083. if not site_packages:
  1084. writefile(site_packages_filename, '')
  1085. else:
  1086. if os.path.exists(site_packages_filename):
  1087. logger.info('Deleting %s' % site_packages_filename)
  1088. os.unlink(site_packages_filename)
  1089. if is_pypy or is_win:
  1090. stdinc_dir = join(prefix, 'include')
  1091. else:
  1092. stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1093. if os.path.exists(stdinc_dir):
  1094. copyfile(stdinc_dir, inc_dir)
  1095. else:
  1096. logger.debug('No include dir %s' % stdinc_dir)
  1097. # pypy never uses exec_prefix, just ignore it
  1098. if sys.exec_prefix != prefix and not is_pypy:
  1099. if sys.platform == 'win32':
  1100. exec_dir = join(sys.exec_prefix, 'lib')
  1101. elif is_jython:
  1102. exec_dir = join(sys.exec_prefix, 'Lib')
  1103. else:
  1104. exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1105. for fn in os.listdir(exec_dir):
  1106. copyfile(join(exec_dir, fn), join(lib_dir, fn))
  1107. if is_jython:
  1108. # Jython has either jython-dev.jar and javalib/ dir, or just
  1109. # jython.jar
  1110. for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  1111. src = join(prefix, name)
  1112. if os.path.exists(src):
  1113. copyfile(src, join(home_dir, name))
  1114. # XXX: registry should always exist after Jython 2.5rc1
  1115. src = join(prefix, 'registry')
  1116. if os.path.exists(src):
  1117. copyfile(src, join(home_dir, 'registry'), symlink=False)
  1118. copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  1119. symlink=False)
  1120. mkdir(bin_dir)
  1121. py_executable = join(bin_dir, os.path.basename(sys.executable))
  1122. if 'Python.framework' in prefix:
  1123. if re.search(r'/Python(?:-32|-64)*$', py_executable):
  1124. # The name of the python executable is not quite what
  1125. # we want, rename it.
  1126. py_executable = os.path.join(
  1127. os.path.dirname(py_executable), 'python')
  1128. logger.notify('New %s executable in %s', expected_exe, py_executable)
  1129. pcbuild_dir = os.path.dirname(sys.executable)
  1130. pyd_pth = os.path.join(lib_dir, 'site-packages', 'virtualenv_builddir_pyd.pth')
  1131. if is_win and os.path.exists(os.path.join(pcbuild_dir, 'build.bat')):
  1132. logger.notify('Detected python running from build directory %s', pcbuild_dir)
  1133. logger.notify('Writing .pth file linking to build directory for *.pyd files')
  1134. writefile(pyd_pth, pcbuild_dir)
  1135. else:
  1136. pcbuild_dir = None
  1137. if os.path.exists(pyd_pth):
  1138. logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
  1139. os.unlink(pyd_pth)
  1140. if sys.executable != py_executable:
  1141. ## FIXME: could I just hard link?
  1142. executable = sys.executable
  1143. if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'):
  1144. # Cygwin misreports sys.executable sometimes
  1145. executable += '.exe'
  1146. py_executable += '.exe'
  1147. logger.info('Executable actually exists in %s' % executable)
  1148. shutil.copyfile(executable, py_executable)
  1149. make_exe(py_executable)
  1150. if sys.platform == 'win32' or sys.platform == 'cygwin':
  1151. pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  1152. if os.path.exists(pythonw):
  1153. logger.info('Also created pythonw.exe')
  1154. shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
  1155. # we need to copy the DLL to enforce that windows will load the correct one.
  1156. # may not exist if we are cygwin.
  1157. py_executable_dll = 'python%s%s.dll' % (
  1158. sys.version_info[0], sys.version_info[1])
  1159. pythondll = os.path.join(os.path.dirname(sys.executable), py_executable_dll)
  1160. if os.path.exists(pythondll):
  1161. logger.info('Also created %s' % py_executable_dll)
  1162. shutil.copyfile(pythondll, os.path.join(os.path.dirname(py_executable), py_executable_dll))
  1163. if is_pypy:
  1164. # make a symlink python --> pypy-c
  1165. python_executable = os.path.join(os.path.dirname(py_executable), 'python')
  1166. logger.info('Also created executable %s' % python_executable)
  1167. copyfile(py_executable, python_executable)
  1168. if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1169. secondary_exe = os.path.join(os.path.dirname(py_executable),
  1170. expected_exe)
  1171. py_executable_ext = os.path.splitext(py_executable)[1]
  1172. if py_executable_ext == '.exe':
  1173. # python2.4 gives an extension of '.4' :P
  1174. secondary_exe += py_executable_ext
  1175. if os.path.exists(secondary_exe):
  1176. logger.warn('Not overwriting existing %s script %s (you must use %s)'
  1177. % (expected_exe, secondary_exe, py_executable))
  1178. else:
  1179. logger.notify('Also creating executable in %s' % secondary_exe)
  1180. shutil.copyfile(sys.executable, secondary_exe)
  1181. make_exe(secondary_exe)
  1182. if 'Python.framework' in prefix:
  1183. logger.debug('MacOSX Python framework detected')
  1184. # Make sure we use the the embedded interpreter inside
  1185. # the framework, even if sys.executable points to
  1186. # the stub executable in ${sys.prefix}/bin
  1187. # See http://groups.google.com/group/python-virtualenv/
  1188. # browse_thread/thread/17cab2f85da75951
  1189. original_python = os.path.join(
  1190. prefix, 'Resources/Python.app/Contents/MacOS/Python')
  1191. shutil.copy(original_python, py_executable)
  1192. # Copy the framework's dylib into the virtual
  1193. # environment
  1194. virtual_lib = os.path.join(home_dir, '.Python')
  1195. if os.path.exists(virtual_lib):
  1196. os.unlink(virtual_lib)
  1197. copyfile(
  1198. os.path.join(prefix, 'Python'),
  1199. virtual_lib)
  1200. # And then change the install_name of the copied python executable
  1201. try:
  1202. call_subprocess(
  1203. ["install_name_tool", "-change",
  1204. os.path.join(prefix, 'Python'),
  1205. '@executable_path/../.Python',
  1206. py_executable])
  1207. except:
  1208. logger.fatal(
  1209. "Could not call install_name_tool -- you must have Apple's development tools installed")
  1210. raise
  1211. # Some tools depend on pythonX.Y being present
  1212. py_executable_version = '%s.%s' % (
  1213. sys.version_info[0], sys.version_info[1])
  1214. if not py_executable.endswith(py_executable_version):
  1215. # symlinking pythonX.Y > python
  1216. pth = py_executable + '%s.%s' % (
  1217. sys.version_info[0], sys.version_info[1])
  1218. if os.path.exists(pth):
  1219. os.unlink(pth)
  1220. os.symlink('python', pth)
  1221. else:
  1222. # reverse symlinking python -> pythonX.Y (with --python)
  1223. pth = join(bin_dir, 'python')
  1224. if os.path.exists(pth):
  1225. os.unlink(pth)
  1226. os.symlink(os.path.basename(py_executable), pth)
  1227. if sys.platform == 'win32' and ' ' in py_executable:
  1228. # There's a bug with subprocess on Windows when using a first
  1229. # argument that has a space in it. Instead we have to quote
  1230. # the value:
  1231. py_executable = '"%s"' % py_executable
  1232. cmd = [py_executable, '-c', """
  1233. import sys
  1234. prefix = sys.prefix
  1235. if sys.version_info[0] == 3:
  1236. prefix = prefix.encode('utf8')
  1237. if hasattr(sys.stdout, 'detach'):
  1238. sys.stdout = sys.stdout.detach()
  1239. elif hasattr(sys.stdout, 'buffer'):
  1240. sys.stdout = sys.stdout.buffer
  1241. sys.stdout.write(prefix)
  1242. """]
  1243. logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
  1244. try:
  1245. proc = subprocess.Popen(cmd,
  1246. stdout=subprocess.PIPE)
  1247. proc_stdout, proc_stderr = proc.communicate()
  1248. except OSError:
  1249. e = sys.exc_info()[1]
  1250. if e.errno == errno.EACCES:
  1251. logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
  1252. sys.exit(100)
  1253. else:
  1254. raise e
  1255. proc_stdout = proc_stdout.strip().decode("utf-8")
  1256. proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
  1257. norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
  1258. if hasattr(norm_home_dir, 'decode'):
  1259. norm_home_dir = norm_home_dir.decode(sys.getfilesystemencoding())
  1260. if proc_stdout != norm_home_dir:
  1261. logger.fatal(
  1262. 'ERROR: The executable %s is not functioning' % py_executable)
  1263. logger.fatal(
  1264. 'ERROR: It thinks sys.prefix is %r (should be %r)'
  1265. % (proc_stdout, norm_home_dir))
  1266. logger.fatal(
  1267. 'ERROR: virtualenv is not compatible with this system or executable')
  1268. if sys.platform == 'win32':
  1269. logger.fatal(
  1270. 'Note: some Windows users have reported this error when they '
  1271. 'installed Python for "Only this user" or have multiple '
  1272. 'versions of Python installed. Copying the appropriate '
  1273. 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
  1274. 'this problem.')
  1275. sys.exit(100)
  1276. else:
  1277. logger.info('Got sys.prefix result: %r' % proc_stdout)
  1278. pydistutils = os.path.expanduser('~/.pydistutils.cfg')
  1279. if os.path.exists(pydistutils):
  1280. logger.notify('Please make sure you remove any previous custom paths from '
  1281. 'your %s file.' % pydistutils)
  1282. ## FIXME: really this should be calculated earlier
  1283. fix_local_scheme(home_dir)
  1284. return py_executable
  1285. def install_activate(home_dir, bin_dir, prompt=None):
  1286. home_dir = os.path.abspath(home_dir)
  1287. if sys.platform == 'win32' or is_jython and os._name == 'nt':
  1288. files = {
  1289. 'activate.bat': ACTIVATE_BAT,
  1290. 'deactivate.bat': DEACTIVATE_BAT,
  1291. 'activate.ps1': ACTIVATE_PS,
  1292. }
  1293. # MSYS needs paths of the form /c/path/to/file
  1294. drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
  1295. home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
  1296. # Run-time conditional enables (basic) Cygwin compatibility
  1297. home_dir_sh = ("""$(if [ "$OSTYPE" == "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" %
  1298. (home_dir, home_dir_msys))
  1299. files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
  1300. else:
  1301. files = {'activate': ACTIVATE_SH}
  1302. # suppling activate.fish in addition to, not instead of, the
  1303. # bash script support.
  1304. files['activate.fish'] = ACTIVATE_FISH
  1305. # same for csh/tcsh support...
  1306. files['activate.csh'] = ACTIVATE_CSH
  1307. files['activate_this.py'] = ACTIVATE_THIS
  1308. if hasattr(home_dir, 'decode'):
  1309. home_dir = home_dir.decode(sys.getfilesystemencoding())
  1310. vname = os.path.basename(home_dir)
  1311. for name, content in files.items():
  1312. content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
  1313. content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
  1314. content = content.replace('__VIRTUAL_ENV__', home_dir)
  1315. content = content.replace('__VIRTUAL_NAME__', vname)
  1316. content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
  1317. writefile(os.path.join(bin_dir, name), content)
  1318. def install_distutils(home_dir):
  1319. distutils_path = change_prefix(distutils.__path__[0], home_dir)
  1320. mkdir(distutils_path)
  1321. ## FIXME: maybe this prefix setting should only be put in place if
  1322. ## there's a local distutils.cfg with a prefix setting?
  1323. home_dir = os.path.abspath(home_dir)
  1324. ## FIXME: this is breaking things, removing for now:
  1325. #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  1326. writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  1327. writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  1328. def fix_local_scheme(home_dir):
  1329. """
  1330. Platforms that use the "posix_local" install scheme (like Ubuntu with
  1331. Python 2.7) need to be given an additional "local" location, sigh.
  1332. """
  1333. try:
  1334. import sysconfig
  1335. except ImportError:
  1336. pass
  1337. else:
  1338. if sysconfig._get_default_scheme() == 'posix_local':
  1339. local_path = os.path.join(home_dir, 'local')
  1340. if not os.path.exists(local_path):
  1341. os.mkdir(local_path)
  1342. for subdir_name in os.listdir(home_dir):
  1343. if subdir_name == 'local':
  1344. continue
  1345. os.symlink(os.path.abspath(os.path.join(home_dir, subdir_name)), \
  1346. os.path.join(local_path, subdir_name))
  1347. def fix_lib64(lib_dir):
  1348. """
  1349. Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  1350. instead of lib/pythonX.Y. If this is such a platform we'll just create a
  1351. symlink so lib64 points to lib
  1352. """
  1353. if [p for p in distutils.sysconfig.get_config_vars().values()
  1354. if isinstance(p, basestring) and 'lib64' in p]:
  1355. logger.debug('This system uses lib64; symlinking lib64 to lib')
  1356. assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1357. "Unexpected python lib dir: %r" % lib_dir)
  1358. lib_parent = os.path.dirname(lib_dir)
  1359. assert os.path.basename(lib_parent) == 'lib', (
  1360. "Unexpected parent dir: %r" % lib_parent)
  1361. copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64'))
  1362. def resolve_interpreter(exe):
  1363. """
  1364. If the executable given isn't an absolute path, search $PATH for the interpreter
  1365. """
  1366. if os.path.abspath(exe) != exe:
  1367. paths = os.environ.get('PATH', '').split(os.pathsep)
  1368. for path in paths:
  1369. if os.path.exists(os.path.join(path, exe)):
  1370. exe = os.path.join(path, exe)
  1371. break
  1372. if not os.path.exists(exe):
  1373. logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe))
  1374. raise SystemExit(3)
  1375. if not is_executable(exe):
  1376. logger.fatal('The executable %s (from --python=%s) is not executable' % (exe, exe))
  1377. raise SystemExit(3)
  1378. return exe
  1379. def is_executable(exe):
  1380. """Checks a file is executable"""
  1381. return os.access(exe, os.X_OK)
  1382. ############################################################
  1383. ## Relocating the environment:
  1384. def make_environment_relocatable(home_dir):
  1385. """
  1386. Makes the already-existing environment use relative paths, and takes out
  1387. the #!-based environment selection in scripts.
  1388. """
  1389. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1390. activate_this = os.path.join(bin_dir, 'activate_this.py')
  1391. if not os.path.exists(activate_this):
  1392. logger.fatal(
  1393. 'The environment doesn\'t have a file %s -- please re-run virtualenv '
  1394. 'on this environment to update it' % activate_this)
  1395. fixup_scripts(home_dir)
  1396. fixup_pth_and_egg_link(home_dir)
  1397. ## FIXME: need to fix up distutils.cfg
  1398. OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  1399. 'activate', 'activate.bat', 'activate_this.py']
  1400. def fixup_scripts(home_dir):
  1401. # This is what we expect at the top of scripts:
  1402. shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir))
  1403. # This is what we'll put:
  1404. new_shebang = '#!/usr/bin/env python%s' % sys.version[:3]
  1405. activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this"
  1406. if sys.platform == 'win32':
  1407. bin_suffix = 'Scripts'
  1408. else:
  1409. bin_suffix = 'bin'
  1410. bin_dir = os.path.join(home_dir, bin_suffix)
  1411. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1412. for filename in os.listdir(bin_dir):
  1413. filename = os.path.join(bin_dir, filename)
  1414. if not os.path.isfile(filename):
  1415. # ignore subdirs, e.g. .svn ones.
  1416. continue
  1417. f = open(filename, 'rb')
  1418. lines = f.readlines()
  1419. f.close()
  1420. if not lines:
  1421. logger.warn('Script %s is an empty file' % filename)
  1422. continue
  1423. if not lines[0].strip().startswith(shebang):
  1424. if os.path.basename(filename) in OK_ABS_SCRIPTS:
  1425. logger.debug('Cannot make script %s relative' % filename)
  1426. elif lines[0].strip() == new_shebang:
  1427. logger.info('Script %s has already been made relative' % filename)
  1428. else:
  1429. logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  1430. % (filename, shebang))
  1431. continue
  1432. logger.notify('Making script %s relative' % filename)
  1433. lines = [new_shebang+'\n', activate+'\n'] + lines[1:]
  1434. f = open(filename, 'wb')
  1435. f.writelines(lines)
  1436. f.close()
  1437. def fixup_pth_and_egg_link(home_dir, sys_path=None):
  1438. """Makes .pth and .egg-link files use relative paths"""
  1439. home_dir = os.path.normcase(os.path.abspath(home_dir))
  1440. if sys_path is None:
  1441. sys_path = sys.path
  1442. for path in sys_path:
  1443. if not path:
  1444. path = '.'
  1445. if not os.path.isdir(path):
  1446. continue
  1447. path = os.path.normcase(os.path.abspath(path))
  1448. if not path.startswith(home_dir):
  1449. logger.debug('Skipping system (non-environment) directory %s' % path)
  1450. continue
  1451. for filename in os.listdir(path):
  1452. filename = os.path.join(path, filename)
  1453. if filename.endswith('.pth'):
  1454. if not os.access(filename, os.W_OK):
  1455. logger.warn('Cannot write .pth file %s, skipping' % filename)
  1456. else:
  1457. fixup_pth_file(filename)
  1458. if filename.endswith('.egg-link'):
  1459. if not os.access(filename, os.W_OK):
  1460. logger.warn('Cannot write .egg-link file %s, skipping' % filename)
  1461. else:
  1462. fixup_egg_link(filename)
  1463. def fixup_pth_file(filename):
  1464. lines = []
  1465. prev_lines = []
  1466. f = open(filename)
  1467. prev_lines = f.readlines()
  1468. f.close()
  1469. for line in prev_lines:
  1470. line = line.strip()
  1471. if (not line or line.startswith('#') or line.startswith('import ')
  1472. or os.path.abspath(line) != line):
  1473. lines.append(line)
  1474. else:
  1475. new_value = make_relative_path(filename, line)
  1476. if line != new_value:
  1477. logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
  1478. lines.append(new_value)
  1479. if lines == prev_lines:
  1480. logger.info('No changes to .pth file %s' % filename)
  1481. return
  1482. logger.notify('Making paths in .pth file %s relative' % filename)
  1483. f = open(filename, 'w')
  1484. f.write('\n'.join(lines) + '\n')
  1485. f.close()
  1486. def fixup_egg_link(filename):
  1487. f = open(filename)
  1488. link = f.read().strip()
  1489. f.close()
  1490. if os.path.abspath(link) != link:
  1491. logger.debug('Link in %s already relative' % filename)
  1492. return
  1493. new_link = make_relative_path(filename, link)
  1494. logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
  1495. f = open(filename, 'w')
  1496. f.write(new_link)
  1497. f.close()
  1498. def make_relative_path(source, dest, dest_is_directory=True):
  1499. """
  1500. Make a filename relative, where the filename is dest, and it is
  1501. being referred to from the filename source.
  1502. >>> make_relative_path('/usr/share/something/a-file.pth',
  1503. ... '/usr/share/another-place/src/Directory')
  1504. '../another-place/src/Directory'
  1505. >>> make_relative_path('/usr/share/something/a-file.pth',
  1506. ... '/home/user/src/Directory')
  1507. '../../../home/user/src/Directory'
  1508. >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
  1509. './'
  1510. """
  1511. source = os.path.dirname(source)
  1512. if not dest_is_directory:
  1513. dest_filename = os.path.basename(dest)
  1514. dest = os.path.dirname(dest)
  1515. dest = os.path.normpath(os.path.abspath(dest))
  1516. source = os.path.normpath(os.path.abspath(source))
  1517. dest_parts = dest.strip(os.path.sep).split(os.path.sep)
  1518. source_parts = source.strip(os.path.sep).split(os.path.sep)
  1519. while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
  1520. dest_parts.pop(0)
  1521. source_parts.pop(0)
  1522. full_parts = ['..']*len(source_parts) + dest_parts
  1523. if not dest_is_directory:
  1524. full_parts.append(dest_filename)
  1525. if not full_parts:
  1526. # Special case for the current directory (otherwise it'd be '')
  1527. return './'
  1528. return os.path.sep.join(full_parts)
  1529. ############################################################
  1530. ## Bootstrap script creation:
  1531. def create_bootstrap_script(extra_text, python_version=''):
  1532. """
  1533. Creates a bootstrap script, which is like this script but with
  1534. extend_parser, adjust_options, and after_install hooks.
  1535. This returns a string that (written to disk of course) can be used
  1536. as a bootstrap script with your own customizations. The script
  1537. will be the standard virtualenv.py script, with your extra text
  1538. added (your extra text should be Python code).
  1539. If you include these functions, they will be called:
  1540. ``extend_parser(optparse_parser)``:
  1541. You can add or remove options from the parser here.
  1542. ``adjust_options(options, args)``:
  1543. You can change options here, or change the args (if you accept
  1544. different kinds of arguments, be sure you modify ``args`` so it is
  1545. only ``[DEST_DIR]``).
  1546. ``after_install(options, home_dir)``:
  1547. After everything is installed, this function is called. This
  1548. is probably the function you are most likely to use. An
  1549. example would be::
  1550. def after_install(options, home_dir):
  1551. subprocess.call([join(home_dir, 'bin', 'easy_install'),
  1552. 'MyPackage'])
  1553. subprocess.call([join(home_dir, 'bin', 'my-package-script'),
  1554. 'setup', home_dir])
  1555. This example immediately installs a package, and runs a setup
  1556. script from that package.
  1557. If you provide something like ``python_version='2.4'`` then the
  1558. script will start with ``#!/usr/bin/env python2.4`` instead of
  1559. ``#!/usr/bin/env python``. You can use this when the script must
  1560. be run with a particular Python version.
  1561. """
  1562. filename = __file__
  1563. if filename.endswith('.pyc'):
  1564. filename = filename[:-1]
  1565. f = open(filename, 'rb')
  1566. content = f.read()
  1567. f.close()
  1568. py_exe = 'python%s' % python_version
  1569. content = (('#!/usr/bin/env %s\n' % py_exe)
  1570. + '## WARNING: This file is generated\n'
  1571. + content)
  1572. return content.replace('##EXT' 'END##', extra_text)
  1573. ##EXTEND##
  1574. def convert(s):
  1575. b = base64.b64decode(s.encode('ascii'))
  1576. return zlib.decompress(b).decode('utf-8')
  1577. ##file site.py
  1578. SITE_PY = convert("""
  1579. eJzFPf1z2zaWv/OvwMqTIZXKdD66nR2n7o2TOK333MTbpLO5dT1aSoIs1hTJEqRl7c3d337vAwAB
  1580. kvLHpp3TdGKJBB4eHt43HtDRaHRcljJfiHWxaDIplEyq+UqUSb1SYllUol6l1WK/TKp6C0/n18mV
  1581. VKIuhNqqGFvFQfD0Cz/BU/FplSqDAnxLmrpYJ3U6T7JsK9J1WVS1XIhFU6X5lUjztE6TLP0XtCjy
  1582. WDz9cgyC01zAzLNUVuJGVgrgKlEsxfm2XhW5iJoS5/w8/nPycjwRal6lZQ0NKo0zUGSV1EEu5QLQ
  1583. hJaNAlKmtdxXpZyny3RuG26KJluIMkvmUvzznzw1ahqGgSrWcrOSlRQ5IAMwJcAqEQ/4mlZiXixk
  1584. LMRrOU9wAH7eEitgaBNcM4VkzAuRFfkVzCmXc6lUUm1FNGtqAkQoi0UBOKWAQZ1mWbApqms1hiWl
  1585. 9djAI5Ewe/iTYfaAeeL4fc4BHD/kwc95ejth2MA9CK5eMdtUcpneigTBwk95K+dT/SxKl2KRLpdA
  1586. g7weY5OAEVAiS2cHJS3Ht3qFvjsgrCxXJjCGRJS5Mb+kHnFwWoskU8C2TYk0UoT5WzlLkxyokd/A
  1587. cAARSBoMjbNIVW3HodmJAgBUuI41SMlaiWidpDkw64/JnND+e5ovio0aEwVgtZT4tVG1O/9ogADQ
  1588. 2iHAJMDFMqvZ5Fl6LbPtGBD4BNhXUjVZjQKxSCs5r4sqlYoAAGpbIW8B6YlIKqlJyJxp5HZC9Cea
  1589. pDkuLAoYCjy+RJIs06umIgkTyxQ4F7ji3YefxNuT16fH7zWPGWAss1drwBmg0EI7OMEA4qBR1UFW
  1590. gEDHwRn+EcligUJ2heMDXm2Dg3tXOohg7mXc7eMsOJBdL64eBuZYgzKhsQLq99/QZaJWQJ//uWe9
  1591. g+B4F1Vo4vxtsypAJvNkLcUqYf5Czgi+1XC+i8t69Qq4QSGcGkilcHEQwRThAUlcmkVFLkUJLJal
  1592. uRwHQKEZtfVXEVjhfZHv01p3OAEgVEEOL51nYxoxlzDRPqxXqC9M4y3NTDcJ7Dqvi4oUB/B/Pidd
  1593. lCX5NeGoiKH420xepXmOCCEvBOFeSAOr6xQ4cRGLM2pFesE0EiFrL26JItEALyHTAU/K22RdZnLC
  1594. 4ou69W41QoPJWpi1zpjjoGVN6pVWrZ3qIO+9iD93uI7QrFeVBODNzBO6ZVFMxAx0NmFTJmsWr3pT
  1595. EOcEA/JEnZAnqCX0xe9A0WOlmrW0L5FXQLMQQwXLIsuKDZDsMAiE2MNGxij7zAlv4R38C3Dx30zW
  1596. 81UQOCNZwBoUIr8LFAIBkyBzzdUaCY/bNCt3lUyas6YoqoWsaKiHEfuAEX9gY5xr8L6otVHj6eIq
  1597. F+u0RpU00yYzZYuXhzXrx1c8b5gGWG5FNDNNWzqtcXpZuUpm0rgkM7lESdCL9MouO4wZDIxJtrgW
  1598. a7Yy8A7IIlO2IMOKBZXOspbkBAAMFr4kT8smo0YKGUwkMNC6JPjrBE16oZ0lYG82ywEqJDbfc7A/
  1599. gNu/QIw2qxToMwcIoGFQS8HyzdK6Qgeh1UeBb/RNfx4fOPV0qW0TD7lM0kxb+SQPTunhSVWR+M5l
  1600. ib0mmhgKZpjX6Npd5UBHFPPRaBQExh3aKvO1UEFdbQ+BFYQZZzqdNSkavukUTb3+oQIeRTgDe91s
  1601. OwsPNITp9B6o5HRZVsUaX9u5fQRlAmNhj2BPnJOWkewge5z4CsnnqvTSNEXb7bCzQD0UnP908u70
  1602. 88lHcSQuWpU26eqzSxjzJE+ArckiAFN1hm11GbRExZei7hPvwLwTU4A9o94kvjKpG+BdQP1T1dBr
  1603. mMbcexmcvD9+fXYy/fnjyU/Tj6efTgBBsDMy2KMpo3lswGFUMQgHcOVCxdq+Br0e9OD18Uf7IJim
  1604. alpuyy08AEMJLFxFMN+JCPHhVNvgaZovi3BMjX9lJ/yI1Yr2uC4Ov74UR0ci/DW5ScIAvJ62KS/i
  1605. jyQAn7alhK41/IkKNQ6ChVyCsFxLFKnoKXmyY+4ARISWhbasvxZpbt4zH7lDkMRH1ANwmE7nWaIU
  1606. Np5OQyAtdRj4QIeY3WGUkwg6llu361ijgp9KwlLk2GWC/wygmMyoH6LBKLpdTCMQsPU8UZJb0fSh
  1607. 33SKWmY6jfSAIH7E4+AiseIIhWmCWqZKwRMlXkGtM1NFhj8RPsotiQwGQ6jXcJF0sBPfJFkjVeRM
  1608. CogYRR0yompMFXEQOBUR2M526cbjLjUNz0AzIF9WgN6rOpTDzx54KKBgTNiFoRlHS0wzxPSvHBsQ
  1609. DuAkhqiglepAYX0mzk/OxctnL/bRAYEocWGp4zVHm5rmjbQPl7BaV7J2EOZe4YSEYezSZYmaEZ8e
  1610. 3g1zHduV6bPCUi9xJdfFjVwAtsjAziqLn+gNxNIwj3kCqwiamCw4Kz3j6SUYOfLsQVrQ2gP11gTF
  1611. rL9Z+j0O32WuQHVwKEyk1nE6G6+yKm5SdA9mW/0SrBuoN7RxxhUJnIXzmAyNGGgI8FtzpNRGhqDA
  1612. qoZdTMIbQaKGX7SqMCZwZ6hbL+nrdV5s8inHrkeoJqOxZV0ULM282KBdgj3xDuwGIFlAKNYSjaGA
  1613. ky5QtvYBeZg+TBcoS9EAAALTrCjAcmCZ4IymyHEeDoswxq8ECW8l0cLfmCEoODLEcCDR29g+MFoC
  1614. IcHkrIKzqkEzGcqaaQYDOyTxue4s5qDRB9ChYgyGLtLQuJGh38UhKGdx5iolpx/a0M+fPzPbqBVl
  1615. RBCxGU4ajf6SzFtcbsEUpqATjA/F+RVigw24owCmUZo1xf5HUZTsP8F6nmvZBssN8Vhdl4cHB5vN
  1616. Jtb5gKK6OlDLgz//5Ztv/vKMdeJiQfwD03GkRSfH4gN6hz5o/K2xQN+ZlevwY5r73EiwIkl+FDmP
  1617. iN/3TbooxOH+2OpP5OLWsOK/xvkABTI1gzKVgbajFqMnav9J/FKNxBMRuW2jMXsS2qRaK+ZbXehR
  1618. F2C7wdOYF01eh44iVeIrsG4QUy/krLkK7eCejTQ/YKoop5Hlgf3nl4iBzxmGr4wpnqKWILZAi++Q
  1619. /idmm4T8Ga0hkLxoonrx7nZYixniLh4u79Y7dITGzDBVyB0oEX6TBwugbdyXHPxoZxTtnuOMmo9n
  1620. CIylDwzzalcwQsEhXHAtJq7UOVyNPipI04ZVMygYVzWCgga3bsbU1uDIRoYIEr0bE57zwuoWQKdO
  1621. rs9E9GYVoIU7Ts/adVnB8YSQB47Ec3oiwak97L17xkvbZBmlYDo86lGFAXsLjXa6AL6MDICJGFU/
  1622. j7ilCSw+dBaF12AAWMFZG2SwZY+Z8I3rA472RgPs1LP6u3ozjYdA4CJFnD16EHRC+YhHqBRIUxn5
  1623. PXexuCVuf7A7LQ4xlVkmEmm1Q7i6ymNQqO40TMs0R93rLFI8zwrwiq1WJEZq3/vOAkUu+HjImGkJ
  1624. 1GRoyeE0OiJvzxPAULfDhNdVg6kBN3OCGK1TRdYNybSCf8CtoIwEpY+AlgTNgnmolPkT+x1kzs5X
  1625. f9nBHpbQyBBu011uSM9iaDjm/Z5AMur8CUhBDiTsCyO5jqwOMuAwZ4E84YbXcqd0E4xYgZw5FoTU
  1626. DOBOL70AB5/EuGdBEoqQb2slS/GVGMHydUX1Ybr7d+VSkzaInAbkKuh8w5Gbi3DyEEedvITP0H5G
  1627. gnY3ygI4eAYuj5uad9ncMK1Nk4Cz7ituixRoZMqcjMYuqpeGMG76909HTouWWGYQw1DeQN4mjBlp
  1628. HNjl1qBhwQ0Yb827Y+nHbsYC+0ZhoV7I9S3Ef2GVqnmhQgxwe7kL96O5ok8bi+1ZOhvBH28BRuNL
  1629. D5LMdP4Csyz/xiChBz0cgu5NFtMii6TapHlICkzT78hfmh4elpSekTv4SOHUAUwUc5QH7yoQENqs
  1630. PABxQk0AUbkMlXb7+2DvnOLIwuXuI89tvjh8edkn7mRXhsd+hpfq5LauEoWrlfGisVDgavUNOCpd
  1631. mFySb/V2o96OxjChKhREkeLDx88CCcGZ2E2yfdzUW4ZHbO6dk/cxqINeu5dcndkRuwAiqBWRUQ7C
  1632. x3Pkw5F97OTumNgjgDyKYe5YFANJ88m/A+euhYIx9hfbHPNoXZWBH3j9zdfTgcyoi+Q3X4/uGaVD
  1633. jCGxjzqeoB2ZygDE4LRNl0omGfkaTifKKuYt79g25ZgVOsV/mskuB5xO/Jj3xmS08HvNe4Gj+ewR
  1634. PSDMLma/QrCqdH7rJkkzSsoDGvv7qOdMnM2pg2F8PEh3o4w5KfBYnk0GQyF18QwWJuTAftyfjvaL
  1635. jk3udyAgNZ8yUX1U9vQGfLt/5G2qu3uHfajamBgeesaZ/hcDWsKb8ZBd/xINh5/fRRlYYB4NRkNk
  1636. 9xzt/+9ZPvtjJvnAqZht39/RMD0S0O81E9bjDE3r8XHHIA4tu2sCDbAHWIodHuAdHlp/aN7oWxo/
  1637. i1WSEk9Rdz0VG9rrpzQnbtoAlAW7YANwcBn1jvGbpqp435dUYCmrfdzLnAgsczJOGFVP9cEcvJc1
  1638. YmKbzSlt7BTFFENqJNSJYDuTsHXhh+VsVZj0kcxv0gr6gsKNwh8+/HgS9hlAD4OdhsG562i45OEm
  1639. HOE+gmlDTZzwMX2YQo/p8u9LVTeK8AlqttNNclaTbdA++DlZE9IPr8E9yRlv75T3qDFYnq/k/Hoq
  1640. ad8d2RS7OvnpN/gaMbHb8X7xlEqWVAEGM5lnDdKKfWAs3Vs2+Zy2KmoJro6us8W6G9pN50zcMkuu
  1641. RESdF5gF0txIiaKbpNKOYFkVWNkpmnRxcJUuhPytSTKMsOVyCbjgPpJ+FfPwlAwSb7kggCv+lJw3
  1642. VVpvgQSJKvQ2HNUOOA1nW55o5CHJOy5MQKwmOBQfcdr4ngm3MOQycbq/+YCTxBAYO5h9UuQueg7v
  1643. 82KKo06pQHbCSPW3yOlx0B2hAAAjAArzH411Es1/I+mVu9dHa+4SFbWkR0o36C/IGUMo0RiTDvyb
  1644. fvqM6PLWDiyvdmN5dTeWV10srwaxvPKxvLobS1ckcGFt/shIwlAOqbvDMFis4qZ/eJiTZL7idlg4
  1645. iQWSAFGUJtY1MsX1w16SibfaCAipbWfvlx62xScpV2RWBWejNUjkftxP0nG1qfx2OlMpi+7MUzHu
  1646. 7K4CHL/vQRxTndWMurO8LZI6iT25uMqKGYitRXfSApiIbi0Opy3zm+mME60dSzU6/69PP3x4j80R
  1647. 1MhUGlA3XEQ0LDiV6GlSXam+NLVxWAnsSC39mhjqpgHuPTDJxaPs8T9vqdgCGUdsqFigECV4AFQS
  1648. ZZu5hUNh2HmuK4z0c2Zy3vc5EqO8HrWT2kGk4/Pzt8efjkeUfRv978gVGENbXzpcfEwL26Dvv7nN
  1649. LcWxDwi1TjO1xs+dk0frliPut7EGbM+H7zx48RCDPRix+7P8QykFSwKEinUe9jGEenAM9EVhQo8+
  1650. hhF7lXPuJhc7K/adI3uOi+KI/tAOQHcAf98RY4wpEEC7UJGJDNpgqqP0rXm9g6IO0Af6el8cgnVD
  1651. r24k41PUTmLAAXQoa5vtdv+8LRM2ekrWr0++P31/dvr6/PjTD44LiK7ch48HL8TJj58FlWqgAWOf
  1652. KMEqhRqLgsCwuKeExKKA/xrM/CyamvO10Ovt2ZneNFnjOREsHEabE8Nzriiy0Dh9xQlh+1CXAiFG
  1653. mQ6QnAM5VDlDB3YwXlrzYRBV6OJiOuczQ2e10aGXPmhlDmTRFnMM0geNXVIwCK72gldUAl6bqLDi
  1654. zTh9SGkAKW2jbY1GRum53s69sxVlNjq8nCV1hidtZ63oL0IX1/AyVmWWQiT3KrSypLthpUrLOPqh
  1655. 3WtmvIY0oNMdRtYNedY7sUCr9Srkuen+45bRfmsAw5bB3sK8c0mVGlS+jHVmIsRGvKkSylv4apde
  1656. r4GCBcM9txoX0TBdCrNPILgWqxQCCODJFVhfjBMAQmcl/Nz8oZMdkAUWSoRv1ov9v4WaIH7rX34Z
  1657. aF5X2f4/RAlRkOCqnnCAmG7jtxD4xDIWJx/ejUNGjqpkxd8arK0Hh4QSoI60UykRb2ZPIyWzpS71
  1658. 8PUBvtB+Ar3udK9kWenuw65xiBLwREXkNTxRhn4hVl5Z2BOcyrgDGo8NWMzw+J1bEWA+e+LjSmaZ
  1659. LhY/fXt2Ar4jnmRACeItsBMYjvMluJut6+D4eGAHFO51w+sK2bhCF5bqHRax12wwaY0iR729Egm7
  1660. TpQY7vfqZYGrJFUu2hFOm2GZWvwYWRnWwiwrs3anDVLYbUMUR5lhlpieV1RL6vME8DI9TTgkglgJ
  1661. z0mYDDxv6KZ5bYoHs3QOehRULijUCQgJEhcPAxLnFTnnwItKmTNE8LDcVunVqsZ9Bugc0/kFbP7j
  1662. 8eez0/dU0//iZet1DzDnhCKBCddzHGG1HmY74ItbgYdcNZ0O8ax+hTBQ+8Cf7isuFDniAXr9OLGI
  1663. f7qv+BDXkRMJ8gxAQTVlVzwwAHC6DclNKwuMq42D8eNW47WY+WAoF4lnRnTNhTu/Pifalh1TQnkf
  1664. 8/IRGzjLUtMwMp3d6rDuR89xWeKO0yIabgRvh2TLfGbQ9br3ZlcdmvvpSSGeJwWM+q39MUyhVq+p
  1665. no7DbLu4hcJabWN/yZ1cqdNunqMoAxEjt/PYZbJhJaybMwd6Fc09YOJbja6RxEFVPvolH2kPw8PE
  1666. ErsXp5iOdKKEjABmMqQ+ONOAD4UWARQIFeJGjuROxk9feHN0rMH9c9S6C2zjD6AIdVksHbcoKuBE
  1667. +PIbO478itBCPXooQsdTyWVe2JIt/GxW6FU+9+c4KAOUxESxq5L8SkYMa2JgfuUTe0cKlrStR+qL
  1668. 9HLIsIhTcE5vd3B4Xy6GN04Mah1G6LW7ltuuOvLJgw0GT2XcSTAffJVsQPeXTR3xSg6L/PBBtN1Q
  1669. 74eIhYDQVO+DRyGmY34Ld6xPC3iQGhoWeni/7diF5bUxjqy1j50DRqF9oT3YeQWhWa1oW8Y52Wd8
  1670. UesFtAb3qDX5I/tU1+zY3wNHtpyckAXKg7sgvbmNdINOOmHEJ4f42GVKlentwRb9biFvZFaA6wVR
  1671. HR48+NUePBjHNp0yWJL1xdidb8+3w7jRmxazQ3MyAj0zVcL6xbmsDxCdwYzPXZi1yOBS/6JDkiS/
  1672. Ji/5zd9PJ+LN+5/g39fyA8RVeHJwIv4BaIg3RQXxJR99pTsJ8FBFzYFj0Sg8XkjQaKuCr29At+3c
  1673. ozNui+jTHv4xD6spBRa4Vmu+MwRQ5AnScfDWTzBnGOC3OWTV8UaNpzi0KCP9Emmw+9wJntU40C3j
  1674. Vb3O0F44WZJ2NS9GZ6dvTt5/PInrW+Rw83PkZFH82iicjt4jrnA/bCLsk3mDTy4dx/kHmZUDfrMO
  1675. Os0ZFgw6RQhxSWkDTb6PIrHBRVJh5kCU20Uxj7ElsDwfm6s34EiPnfjyXkPvWVmEFY31LlrrzeNj
  1676. oIb4pauIRtCQ+ug5UU9CKJnh+S1+HI+GTfFEUGob/jy93izczLg+iEMT7GLazjryu1tduGI6a3iW
  1677. kwivI7sM5mxmliZqPZu7Z/Y+5EJfJwJajvY55DJpslrIHCSXgny61wE0vXvMjiWEWYXNGZ09ozRN
  1678. tkm2yilCSpQY4agjOpqOGzKUMYQY/Mfkmu0Bnv8TDR8kBuiEKMVPhdNVNfMVSzCHRES9gcKDTZq/
  1679. dOt5NIV5UI6Q560jC/NEt5ExupK1nj8/iMYXz9tKB8pKz71DtvMSrJ7LJnugOsunT5+OxH/c7/0w
  1680. KnFWFNfglgHsQa/ljF7vsNx6cna1+p69eRMDP85X8gIeXFL23D5vckpN3tGVFkTavwZGiGsTWmY0
  1681. 7Tt2mZN2FW80cwvesNKW4+c8pUuDMLUkUdnqu5cw7WSkiVgSFEOYqHmahpymgPXYFg2ej8M0o+YX
  1682. eQscnyKYCb7FHTIOtVfoYVItq+Uei86RGBHgEdWW8Wh0wJhOiAGe0/OtRnN6mqd1e7Tjmbt5qg/S
  1683. 1/YuIM1XItmgZJh5dIjhHLX0WLX1sIs7WdSLWIr5hZtw7MySX9+HO7A2SFqxXBpM4aFZpHkhq7kx
  1684. p7hi6TytHTCmHcLhznQFElmfOBhAaQTqnazCwkq0ffsnuy4uph9oH3nfjKTLh2p7rRQnh5K8U2AY
  1685. x+34lIayhLR8a76MYZT3lNbWnoA3lviTTqpiXb93+4V7xLDJ9a0WXL/RXnUBcOgmJasgLTt6OsK5
  1686. vsvCZ6bdcRcFfihEJ9xu0qpukmyqL0+YosM2tRvrGk97NO3OQ5fWWwEnvwAPeF9X0YPjYKpskJ5Y
  1687. BGtOSRyJpU5RxO5pL/9gVFmgl/eCfSXwKZAyi6k5o2ySSBeWXe3hT12z6ah4BPWVOVD0EJtgjrX0
  1688. ToS405hQ0VM47la59lrhBos5tmA9725k8KghO7B8L95MsHunhfjuSETPJ+LPnUBsXm7xViYgw5NF
  1689. /GQR+j4hdb04fNHauX7g24GwE8jLy0dPN0tnNL1wqPz8/r666BED0DXI7jKVi/0nCrFjnL8UqobS
  1690. zms3p9KM8XT6nq260gez2+MqdCptBlHFplVojmoz/q8dxJz41nqID8ei0mALaA/0m8KXTvGhvXQN
  1691. CxM1ev7KopRMhzbH8BtenALvNUFdodq5aaor7C3YgZyAPkbJW2Btw4Gg8BE8FNIlL7RoX3W2hf/I
  1692. xeOi/V2biz0sv/n6LjxdAR88sTBAUI+YTqs/kKl2ssxjF+YB+/X389/Dee8uvns0lXSvYVphKIWF
  1693. zKuE36BJbMpDm2owIolbQZFb3oaf+nrwTAyLI+qm+jq8a/rc/6656xaBnbnZ3e3N3T/75tJA993N
  1694. L0M04DBPE+JBNeOtwA7rAleMJ7qoYDhlqT9IfrcTznSHVrgPjClhwAQosanG3mjNdTJ3v2OFzD5f
  1695. 7+oedRzU1Z1p985+djn+IYqWqwHwuT39TCUeC82B7DfSfV1TLhqcyqsrNU3wrrgpBRtU4NLzIo37
  1696. +o6u+pKJ2hqvEy9UARCGm3QpolttDIwBAQ3fWcv1Ic7NGYKGpipKpyxTpQvOIGkXF8DFnDmi/iYz
  1697. yXWVo0xiwk81VVlBVDDSN5ty4cJQrWcL1CQy1om6NqibHhN90SUOwdUy5ngk56s40vCoA4TgU1PO
  1698. tU1cqDyd2nfAL8/aY+DpxDKEzJu1rJK6vQLF3yZNxXfOCHQoFhfYSVW0ktnhFBex1PKHgxQmC+z3
  1699. r7ST7QUZd5z9Hlut93C2oh46BfaYY+WO7THcnN7aK9Dcq3cWdGGua+Rts5b77LUvsBTmPi/SlTp3
  1700. wG/1HUN8cyVnNtFNcPgI5N49kuaX51q1xk6KRcN55iqG/qUyeKqZbPHQXXE9LujfCtdx9O34vt6w
  1701. zNILDXY0tlTUrtWg4mlHG7cRNVbS3RNR+9XSj4yoPfgPjKj1zX5gcDQ+Wh8M1k/fE3qzmnCvyWsZ
  1702. AfpMgUi4s9e5ZM2YzMitRoawN70d2WtqWWc6R5yMmUCO7N+fRCD4Ojzllm5611WZcYciWl+66PH3
  1703. Zx9eH58RLabnx2/+8/h7qlbB9HHHZj045ZAX+0ztfa8u1k0/6AqDocFbbAfuneTDHRpC731vc3YA
  1704. wvBBnqEF7Soy9/WuDr0DEf1OgPjd0+5A3aWyByH3/DNdfO/WFXQKWAP9lKsNzS9ny9Y8MjsXLA7t
  1705. zoR53yaTtYz2cm27Fs6p++urE+236psKd+QBx7b6lFYAc8jIXzaFbI4S2EQlOyrd/3kAlcziMSxz
  1706. ywdI4Vw6t83RRXMMqvb/LwUVKLsE98HYYZzYG3+pHafLlb3KGvfC5jI2BPHOQY3683OFfSGzHVQI
  1707. AlZ4+i41RsToP73BZLdjnyhxsU8nLvdR2VzaX7hm2sn9e4qbrrW9k0hx5QZvO0HjZZO5G6m2T68D
  1708. OX+UnS+WTok/aL4DoHMrngrYG30mVoizrQghkNQbhlg1SHTUF4o5yKPddLA3tHom9nedx3PPownx
  1709. fHfDRefIm+7xgnuoe3qoxpx6ciwwlq/tOmgnviPIvL0j6BIiz/nAPUV99y18vbl4fmiTrcjv+NpR
  1710. JFRmM3IM+4VTpnbnxXdOd2KWakJ1TBizOcc0dYtLByr7BLtinF6t/o44yOz7MqSR9364yMf08C70
  1711. HnUxtax3CFMS0RM1pmk5pxs07vbJuD/dVm31gfBJjQcA6alAgIVgerrRqZzbcvlr9ExHhbOGrgx1
  1712. M+6hIxVUReNzBPcwvl+LX7c7nbB8UHdG0fTnBl0O1EsOws2+A7caeymR3SahO/WWD3a4AHxYdbj/
  1713. 8wf079d32e4v7vKrbauXgwek2JfFkkCslOiQyDyOwciA3oxIW2MduRF0vJ+jpaPLUO3ckC/Q8aMy
  1714. Q7wQmAIMcman2gOwRiH4P2ts6wE=
  1715. """)
  1716. ##file ez_setup.py
  1717. EZ_SETUP_PY = convert("""
  1718. eJzNWmtv49a1/a5fwSgwJGE0NN8PDzRFmkyBAYrcIo8CFx5XPk+LHYpUSWoctch/v+ucQ1KkZDrt
  1719. RT6UwcQ2ebjPfq6195G+/upwanZlMZvP538sy6ZuKnKwatEcD01Z5rWVFXVD8pw0GRbNPkrrVB6t
  1720. Z1I0VlNax1qM16qnlXUg7DN5EovaPLQPp7X192PdYAHLj1xYzS6rZzLLhXql2UEI2QuLZ5VgTVmd
  1721. rOes2VlZs7ZIwS3CuX5BbajWNuXBKqXZqZN/dzebWbhkVe4t8c+tvm9l+0NZNUrL7VlLvW58a7m6
  1722. sqwS/zhCHYtY9UGwTGbM+iKqGk5Qe59fXavfsYqXz0VeEj7bZ1VVVmurrLR3SGGRvBFVQRrRLzpb
  1723. utabMqzipVWXFj1Z9fFwyE9Z8TRTxpLDoSoPVaZeLw8qCNoPj4+XFjw+2rPZT8pN2q9Mb6wkCqs6
  1724. 4vdamcKq7KDNa6OqtTw8VYQP42irZJi1zqtP9ey7D3/65uc//7T964cffvz4P99bG2vu2BFz3Xn/
  1725. 6Ocf/qz8qh7tmuZwd3t7OB0y2ySXXVZPt21S1Lc39S3+63e7nVs3ahe79e/9nf8wm+15uOWkIRD4
  1726. Lx2xxfmNt9icum8PJ8/2bfH0tLizFknieYzI1HG90OFJkNA0jWgsvZBFImJksX5FStBJoXFKEhI4
  1727. vghCx5OUJqEQvnTTwI39kNEJKd5YlzAK4zhMeUIinkgWBE7skJQ7sRd7PE1fl9LrEsAAknA3SrlH
  1728. RRS5kvgeiUToiUAm3pRF/lgXSn2XOZLFfpqSyA/jNI1DRngqQ+JEbvKqlF4XPyEJw10eCcY9zwti
  1729. 6capjDmJolQSNiElGOsSeU4QEi8QPBCuoCyOpXD8lJBARDIW4atSzn5h1CNuEkKPhBMmJfW4C30c
  1730. n/rUZcHLUthFvlBfejQM/ZRHiGss44DwOHU9CCKpk0xYxC7zBfZwweHJKOYe96QUbuA4qR8F0iPB
  1731. RKSZ64yVYXCHR2jIfeJ4YRSEEeLDXD9xHBI7qfO6mF6bMOZ4ETFKaeLEscfClIQ+SQLfJyHnk54x
  1732. YsJODBdBRFgCX6YxS9IwjD0RiiREOgqasPh1MVGvTSJQSURIJ4KDPCaiwA0gzYORcPhEtAEqY994
  1733. lAiCGnZ9jvdRRl4iYkpCGhJoxMXrYs6R4pGfypQ6EBawwAvS2PEDLpgnmMO8yUi5Y99EAUsD6VMZ
  1734. kxhZ6AuW+MKhHsIdByn1XhfT+4ZKknqu41COMHHUBCQJzn0EPgqcJJoQc4Ez0nGigMqIEI/G3IFa
  1735. 8GyAxHYSN2beVKAucCZyIzf1hGB+KINYIGpuxHhEXA9SvXhKygXOSDcBQAF8uUSqEC9MWQop0uUx
  1736. jRM5gVbsAmeEI3gcRInH0jShksbwdOIgex3EPHangu2Pg0SokG4kOYdhYRi6QRK4LAZ+8TRJo3BK
  1737. ygVaUYemru8SRqjvOXAGcC6WQcBCAEXsylel9BYhSST2jHggqfRRUVSmQcQcuAqoJ6YSJhhblCi0
  1738. BvD7HuM0ZbFHmQwAX14kvYTIKbQKxxYJkUqeOFAHBYmMlb4ApocxAIMnbjQV6XBsEZHAKi7BKm7s
  1739. uELAuTHIKaQMhEeiKZQJL2KUcF9GAISAMUKS2A2QONyPKWPc5yGfkBKNLULBJGD5xHUjMFGSBLEH
  1740. EWDMMEhR2lPAGV2wGwsjIsOYwr/oHlANkQNDgsBHgYVkChuisUXUkwmJQw9kD9ilPkjaQai5CCVa
  1741. idCfkBJfwJ2DGMmUcOaTyA1F6LohyhAtRQIInMyX+IIJSCLTMAALcGC5I2kUM+lKD2HAI2+qAuKx
  1742. RQE4lgBvJVoGFGDgB67rSi4S38W/eEqX5KIbclQv5KXwSMrBHyoFAeCJ76jGynldSm8Ro8RPgA3o
  1743. OYLEZ47KWWQbnM3ALJM0kIwtcmPPjQFyCHTKmRs6YeqQMKG+QJ2n4VSk07FF0J0FDpoZV3mYBmkk
  1744. AiapcBLYypypSKcXyIAkQ2MHbvWThEdAJyKEEwG8WOQHU/1dK6W3SAqE1hchcWPqegxhYmHg0hjc
  1745. C+YXU0ySjvmIEZSNKxVqEk9wAJOb+mC2mIaphx4HUn6dDSYCjDf1rKlOd2bg2pF6l2e0m7fQu8/E
  1746. L0xg1Pio73xQI1G7Fg+H62ZcSGv7heQZun2xxa0ldNoWmAfXlhoAVnfagExa3X01M3bjgXmoLp5h
  1747. tmgwLigR+kV7J34xdzHfdcsgp1351aaXct+JfjjLUxfmLkyD79+r6aRuuKgw1y1HK9Q1Vya1FrTz
  1748. 4Q2mMIIxjH9lWcu/lHWd0Xww/mGkw9/7P6zmV8JuejNHj1ajv5Q+4pesWXrmfoXgVoV2l3HoxXCo
  1749. F7Xj1eZimFv3am0pqcVmMNCtMSluMapuytpmxwq/mWTqX+AiJ6eNG87aIGFs/ObYlHv4gWG6PGEU
  1750. Lfhtb/bgpEDN9XvyGbHE8PwFriLKQXCeMu1Amp0Z5x9bpR+telcec66mWWJ8PZTWTebFcU9FZTU7
  1751. 0lgYhHvBWpaagAvlXUti6u2VOhZcvyKsx5EjHi010i6fdxnbdbsLaK2OJow8a3G7WNlQ0njpUW2p
  1752. 5AyOMXaiGh2QPGeYuek5EwRfIyNNgmuVixL+yCtB+OmsPvb4KAfqabfr7dqzCS2mabXU0qjQqrQO
  1753. 0ScWrCx4bXzTqXEgSBTlVHhElVXWZAhd8TQ4zzARb+0vC6HPE8zZCDd6wallrnz44vmI0rI9bBCt
  1754. MH2WU5VH7CSMKqbOiLUXdU2ehDngOBfd46POl4pktbB+PNWN2H/4RfmrMIEoLNLgnjnZIFRBizJe
  1755. paAyxpx62F2G6p/PpN4aFIL9G2tx+Py0rURdHism6oVCGLX9vuTHXNTqlGQAoJePTU2g6jjyoHXb
  1756. cnVGEpVym3PRDOqy9dhFCXZlt74otDMGdEViw7OiapbOWm0yALkWqPud3g1Pd2h3zLdtA7PVwLxR
  1757. MkyAAOyXskYO0g9fQPj+pQ6Qhg5pH13vMBJtt8m1nJ81fr+Zv2ldtXrXyh6qMBbwV7Py27KQecaa
  1758. QRxgokFOBstluVzduw9DYhgmxX9KBPOfdufCmCiF5fvNTb3qy7wrb33K+akYc8GckWLRqGrrqwdw
  1759. ok72dPm0J3mqkI5FgSy3rb/kAsnTLb+Sp8pLVTmwScCWTkOZVXWzBmGoSllAwqnLCuvtzwPlF/aF
  1760. vE/Fp2L57bGqIA1IbwTcVBeUtgKhndNc2KR6qu+dh9fp7MWwfpchZzN6VBT7fdn8qQRwD3KI1PWs
  1761. LcR8/OZ6WKv3F5X+oF75Gk7RXFB+HtHpMHsNr75UxL83uapSR6aOWPW7FyhUFy05U4CVl8w0IBos
  1762. jQ1ZY86DdUPxX0qpBpDViX9Hqb/FqOqe2vWaTg3KP54ZcoIFS8N9HfUpCmHNkeRnI1pKGdNG94FC
  1763. BWahHjJrh3zMTdJ23enGGkDX25sanfZNrRrt+bAWLg68TeJD7pAplM+sN+OGsCZfBLTfoAE3FPD3
  1764. MiuWHWF0S424umJKnO6Kvwd3d420Qp/uddRd3dRLI3Z1p4rhmy9lphLoIIhix06dui+2EXqrS6ci
  1765. hyDljbrzUl4+jVap1lvFZfyuurDSfiZVsVR+fvv7XebzkBYrW3CuX8ryG50S6nOSpfgiCvUHzDlA
  1766. 2dlO5AfV5X002TboNPpUQSui8l99krNUrpgB5dcWoGqmbu1RzoWAI/EK6lD1uQBd8awglmB4rWv9
  1767. 9hDWNSjbs3ZLoHHb0Zx3hMq8y2Z7NlsCEcWd8rAWsydsp5orXgrDNTuEF0o0z2X1ud10bR0MYZS0
  1768. Ie2ncAopNErcAEwVisADTPfoegEknyuxrZxKtAQ0NMBe/Z5RRFKsr1JmALpX7ZPOsrWqpqvX0D/o
  1769. ZG0yNUe2bVIuxOGd+bG86LTG2dnBsKa6eq63uKAyXXItPtj4WR5Esbxa9rX1A1r82+cqawA+iDH8
  1770. q5trYPjntfog8FlFT3UArFJlCGhkZVUddXLk4kKYjvswPVTP3Qi9vsPE7mo/VJsauWGArcaP5Wqs
  1771. sUERbY3BivX8mc7hTjywtR1m6O5fwuinRsC7SwjABnd6F5aXtViuriCibu600OHzls060IKCufql
  1772. g63Zv3Mp/t4j05foQb6spxj7zLkfX/uIVHPsB3RL7aqOIF5qnS8+en6tbzajQo/VVxLPa14fJ/Rc
  1773. 7lx3WeOhYTQz6Jip0hhMCqzc72GoPWoLu8Mb0o5f3dXGSLs4BxdoP6/eqLOVh5VO02exqHRaC0vR
  1774. +G+mirJU+fmCq5Ta1xyCRccC897nZW+WyGsxiMawF7e329Zb2621wQDo2I7tLv7jrv9/AfAaXNUU
  1775. TOsyF6jViUG46+NBJqZXv+rRK7Evv2i81ZEw33DQ8y6YowH05r+BuxfN92SX3RbVP8bNymDOGnY7
  1776. 16PfvzG+4ecrzfzkjPZya/H/ScnXyqwX/JtSrrL5pbrryu1hPKFrZzsrJD6sUuyPwDGdKerJyxmq
  1777. dvmdHNCrrzU/+2W0pQ6gSvPl/Mertmi+7hBlDhB80kRUqcNeJCGapHNCz1cvCFwsf0A/Ne++jGMf
  1778. TuOJcm6+ZnP9TRR7tWjHreOhZ6huiKnPAP2zfmqpIqHHLG/emnNhyHxSs+JJYfIwj6t2AlLdVneO
  1779. 3Is9u0R33ef+Wv2pVizPfbUW0rGhps1FRRfnZ/2xsnr3oT2Slh2tvngsLXu6M0OgIen7ufrjprrD
  1780. vzXQAgNE22ualqzbyAb97uvl6qF/2a5hcU+eBzVWzOdmVjA0PXQMQoAhsulmBv39oU13134SjSlb
  1781. dX85nKW3umfYbtu8713Sylhb2i3v2qaoc8C7S2P3pME8uIGedi1IxXbL+adi+P2fT8Xy/m+/PrxZ
  1782. /TrXDcpqOMjotwdo9AJmg8r1N7BySygc+Gp+XaYdJhpV8f/7Oy3Y1s330l09YBDTjnyjn5qHGF7x
  1783. 6O7hZfMXz21OyLZB6lUfOGAGMzo/bjaL7VaV7Ha76D/1yJVEqKmr+L2nCbH7+959wDtv38JZplQG
  1784. BDaonX65d/fwEjNqlDjLVIvM9X+XVxF7
  1785. """)
  1786. ##file distribute_setup.py
  1787. DISTRIBUTE_SETUP_PY = convert("""
  1788. eJztG2tz2zbyu34FTh4PqYSi7TT3GM+pM2nj9DzNJZnYaT8kHhoiIYk1X+XDsvrrb3cBkCAJyc61
  1789. dzM3c7qrIxGLxWLfuwCP/lTs6k2eTabT6Xd5Xld1yQsWxfBvvGxqweKsqnmS8DoGoMnliu3yhm15
  1790. VrM6Z00lWCXqpqjzPKkAFkdLVvDwjq+FU8lBv9h57JemqgEgTJpIsHoTV5NVnCB6+AFIeCpg1VKE
  1791. dV7u2DauNyyuPcaziPEoogm4IMLWecHylVxJ4z8/n0wYfFZlnhrUBzTO4rTIyxqpDTpqCb7/yJ2N
  1792. dliKXxsgi3FWFSKMV3HI7kVZATOQhm6qh98BKsq3WZLzaJLGZZmXHstL4hLPGE9qUWYceKqBuh17
  1793. tGgIUFHOqpwtd6xqiiLZxdl6gpvmRVHmRRnj9LxAYRA/bm+HO7i99SeTa2QX8TekhRGjYGUD3yvc
  1794. SljGBW1PSZeoLNYlj0x5+qgUE8W8vNLfql37tY5Tob+vspTX4aYdEmmBFLS/eUk/Wwk1dYwqI0eT
  1795. fD2Z1OXuvJNiFaP2yeFPVxcfg6vL64uJeAgFkH5Jzy+QxXJKC8EW7F2eCQObJrtZAgtDUVVSVSKx
  1796. YoFU/iBMI/cZL9fVTE7BD/4EZC5s1xcPImxqvkyEN2PPaaiFK4FfZWag90PgqEvY2GLBTid7iT4C
  1797. RQfmg2hAihFbgRQkQeyF/80fSuQR+7XJa1AmfNykIquB9StYPgNd7MDgEWIqwNyBmBTJdwDmmxdO
  1798. t6QmCxEK3OasP6bwOPA/MG4YHw8bbHOmx9XUYccIOIJTMMMhtenPHQXEOviiVqxuhtLJK78qOFid
  1799. C98+BD+/urz22IBp7Jkps9cXb159ensd/HTx8ery/TtYb3rq/8V/8XLaDn36+BYfb+q6OD85KXZF
  1800. 7EtR+Xm5PlFOsDqpwFGF4iQ66fzSyXRydXH96cP1+/dvr4I3r368eD1YKDw7m05MoA8//hBcvnvz
  1801. Hsen0y+Tf4qaR7zm85+kOzpnZ/7p5B340XPDhCft6HE1uWrSlINVsAf4TP6Rp2JeAIX0e/KqAcpL
  1802. 8/tcpDxO5JO3cSiySoG+FtKBEF58AASBBPftaDKZkBorX+OCJ1jCvzNtA+IBYk5IyknuXQ7TYJ0W
  1803. 4CJhy9qb+OldhN/BU+M4uA1/y8vMdS46JKADx5XjqckSME+iYBsBIhD/WtThNlIYWi9BUGC7G5jj
  1804. mlMJihMR0oX5eSGydhctTKD2obbYm+yHSV4JDC+dQa5zRSxuug0ELQD4E7l1IKrg9cb/BeAVYR4+
  1805. TECbDFo/n97MxhuRWLqBjmHv8i3b5uWdyTENbVCphIZhaIzjsh1kr1vddmamO8nyuufAHB2xYTlH
  1806. IXcGHqRb4Ap0FEI/4N+Cy2LbMoevUVNqXTGTE99YeIBFCIIW6HlZCi4atJ7xZX4v9KRVnAEemypI
  1807. zZlpJV42MTwQ67UL/3laWeFLHiDr/q/T/wM6TTKkWJgxkKIF0XcthKHYCNsJQsq749Q+HZ//in+X
  1808. 6PtRbejRHH/Bn9JA9EQ1lDuQUU1rVymqJqn7ygNLSWBlg5rj4gGWrmi4W6XkMaSol+8pNXGd7/Mm
  1809. iWgWcUraznqNtqKsIAKiVQ7rqnTYa7PaYMkroTdmPI5EwndqVWTlUA0UvNOFyflxNS92x5EP/0fe
  1810. WRMJ+ByzjgoM6uoHRJxVDjpkeXh2M3s6e5RZAMHtXoyMe8/+99E6+OzhUqdXjzgcAqScDckHfyjK
  1811. 2j31WCd/lf326x4jyV/qqk8H6IDS7wWZhpT3oMZQO14MUqQBBxZGmmTlhtzBAlW8KS1MWJz92QPh
  1812. BCt+JxbXZSNa75pyMvGqgcJsS8kz6ShfVnmChoq8mHRLGJoGIPiva3Jvy6tAckmgN3WKu3UAJkVZ
  1813. W0VJLPI3zaMmERVWSl/a3TgdV4aAY0/c+2GIprdeH0Aq54ZXvK5LtwcIhhJERtC1JuE4W3HQnoXT
  1814. UL8CHoIo59DVLi3EvrKmnSlz79/jLfYzr8cMX5Xp7rRjybeL6XO12sxC1nAXfXwqbf4+z1ZJHNb9
  1815. pQVoiawdQvIm7gz8yVBwplaNeY/TIdRBRuJvSyh03RHE9Jo8O20rMnsORm/G/XZxDAUL1PooaH4P
  1816. 6TpVMl+y6RgftlJCnjk11pvK1AHzdoNtAuqvqLYAfCubDKOLzz4kAsRjxadbB5yleYmkhpiiaUJX
  1817. cVnVHpgmoLFOdwDxTrscNv9k7MvxLfBfsi+Z+31TlrBKspOI2XE5A+Q9/y98rOIwcxirshRaXLsv
  1818. +mMiqSz2ARrIBiZn2PfngZ+4wSkYmamxk9/tK2a/xhqeFEP2WYxVr9tsBlZ9l9dv8iaLfrfRPkqm
  1819. jcRRqnPIXQVhKXgtht4qwM2RBbZZFIarA1H698Ys+lgCl4pXygtDPfy6a/G15kpxtW0kgu0leUil
  1820. C7U5FePjWnbuMqjkZVJ4q2i/ZdWGMrMltiPveRL3sGvLy5p0KUqwaE6m3HoFwoXtP0p6qWPS9iFB
  1821. C2iKYLc9ftwy7HG44CPCjV5dZJEMm9ij5cw5cWY+u5U8ucUVe7k/+BdRCp1Ctv0uvYqIfLlH4mA7
  1822. Xe2BOqxhnkXU6yw4BvqlWKG7wbZmWDc86TqutL8aK6na12L4jyQMvVhEQm1KqIKXFIUEtrlVv7lM
  1823. sKyaGNZojZUGihe2ufX6twDVAVs/veTYxzJs/Rs6QCV92dQue7kqCpI9b7HI/I/fC2DpnhRcg6rs
  1824. sgwRHexLtVYNax3kzRLt7Bx5/uo+j1GrC7TcqCWny3BGIb0tXlrrIR9fTT3cUt9lS6IUl9zR8BH7
  1825. KHh0QrGVYYCB5AxIZ0swuTsPO+xbVEKMhtK1gCaHeVmCuyDrGyCD3ZJWa3uJ8ayjFgSvVVh/sCmH
  1826. CUIZgj7waJBRSTYS0ZJZHptul9MRkEoLEFk3NvKZShKwliXFAAJ0iT6AB/yWcAeLmvBd55QkDHtJ
  1827. yBKUjFUlCO66Au+1zB/cVZOF6M2UE6Rhc5zaqx579uxuOzuQFcvmf1efqOnaMF5rz3Ilnx9KmIew
  1828. mDNDIW1LlpHa+ziXraRRm938FLyqRgPDlXxcBwQ9ft4u8gQcLSxg2j+vwGMXKl2wSHpCYtNNeMMB
  1829. 4Mn5/HDefhkq3dEa0RP9o9qslhnTfZhBVhFYkzo7pKn0pt4qRSeqAvQNLpqBB+4CPEBWdyH/Z4pt
  1830. PLxrCvIWK5lYi0zuCCK7DkjkLcG3BQqH9giIeGZ6DeDGGHahl+44dAQ+DqftNPMsPa1XfQizXap2
  1831. 3WlDN+sDQmMp4OsJkE1ibAjIGRDFMp8zNwGGtnVswVK5Nc07eya4svkh0u2JIQZYz/Quxoj2TXio
  1832. rNlmFZp2cUPeGzxWqEZ7lggysdWRGZ9ClHX8929f+8cVHmnh6aiPf0ad3Y+ITgY3DCS57ClKEjVO
  1833. 1eTF2hZ/urZRtQH9sCU2ze8hWQbTCMwOuVskPBQbUHahO9WDMB5X2Gscg/Wp/5TdQSDsNd8h8VJ7
  1834. MObu168V1h09/4PpqL4QYDSC7aQA1eq02Vf/ujjXM/sxz7BjOMfiYOju9eIjb7kE6d+ZbFn1y6OO
  1835. A12HlFJ489DcXHfAgMlIC0BOqAUiEfJINm9qTHrRe2z5rrM5XecMEzaDPR6Tqq/IH0hUzTc40Tlz
  1836. ZTlAdtCDla6qF0FGk6Q/VDM8ZjmvVJ1txdGRb++4AabAhy7KY31qrMp0BJi3LBG1UzFU/Nb5DvnZ
  1837. KpriN+qaa7bwvEHzT7Xw8SYCfjW4pzEckoeC6R2HDfvMCmRQ7ZreZoRlHNNteglOVTbuga2aWMWJ
  1838. PW1056q7yBMZbQJnsJO+P97na4beeR+c9tV8Bel0e0SM6yumGAEMQdobK23burWRjvdYrgAGPBUD
  1839. /5+mQESQL39xuwNHX/e6CygJoe6Ske2xLkPPuUm6v2ZKz+Wa5IJKWoqpx9ywRdiaObqxMHZBxKnd
  1840. PfEITE5FKvfJpyayIuw2qiKxYUXq0Kbq/CAs8KWnc+6+qwKepO0rnN6AlJH/07wcO0Cr55HgB/zO
  1841. 0Id/j/KXkXw0q0uJWgd5OC2yuk8C2J8iSVbVbU60n1WGjHyY4AyTksFW6o3B0W4r6vFjW+mRYXTK
  1842. hvJ6fH+PmdjQ0zwCPuvl823Q63K6IxVKIAKFd6hKMf6y5dd7FVRmwBc//DBHEWIIAXHK71+hoPEo
  1843. hT0YZ/fFhKfGVcO3d7F1T7IPxKd3Ld/6jw6yYvaIaT/Kuf+KTRms6JUdSlvslYca1Pol+5RtRBtF
  1844. s+9kH3NvOLOczCnM1KwNilKs4gdXe/ouuLRBjkKDOpSE+vveOO839oa/1YU6DfhZf4EoGYkHI2w+
  1845. Pzu/abMoGvT0tTuRNakoubyQZ/ZOEFTeWJX51nxewl7lPQi5iWGCDpsAHD6sWdYVtplRiRcYRiQe
  1846. S2OmzgslGZpZJHHtOrjOwpl9ng9O5wwWaPaZiylcwyMiSRWWhpIK64FrApopbxF+K/lj7yH1yK0+
  1847. E+RzC5VfS2lHIzC3qUTp0NFCdzlWHRViG9fasbGt0s62GIbUyJGqDpX9KuR0oGicO+rrkTbb3Xsw
  1848. fqhDdcS2wgGLCoEES5A3sltQSONWT5QLyZRKiBTPGczj0XGXhH5u0Vz6pYK6d4RsGG/IiEOYmMLk
  1849. beVj1tY/0/c/yvNeTLbBK5bgjHrliT1xH2gLxXzEsCA3rjyu4tz1rhAjvmGr0jhIevXh8g8mfNYV
  1850. gUOEoJB9ZTRvc5nvFpgliSzM7aI5YpGohbo1h8EbT+LbCIiaGg1z2PYYbjEkz9dDQ30233kwih65
  1851. NGi3bodYVlG8oEMF6QtRIckXxg9EbFHm93EkIvn6Q7xS8OaLFpXRfIjUhbvU6w41dMfRrDj6gcNG
  1852. mV0KChsw1BsSDIjkWYjtHuhYW+WNcKBlA/XH/hqll4aBVUo5VuZ1PbUlyyZ8kUUqaNCdsT2byuby
  1853. Nl8nvB4daN/7+2hWqerJijTAYfOwlqaKceFzP0n7MiYLKYcTKEWiuy//RJ3rdyO+Igfdm4QeaD4P
  1854. eNOfN24/m7rRHt2hWdP5snR/dNZr+PtMDEXbz/5/rzwH9NJpZyaMhnnCmyzcdClc92QYKT+qkd6e
  1855. MbSxDcfWFr6RJCGo4NdvtEioIi5Yyss7PMvPGacDWN5NWDat8bSp3vk3N5gufHbmoXkjm7IzvGKT
  1856. iLlqAczFA72/BDnzPOUZxO7IuTFCnMZ4etP2A7BpZiaYn/tvXNyw5+20icZB93OsL9O03DMuJVci
  1857. WcnG+WLqTz2WCrw4UC0wpnQnM+oiNR0EKwh5zEiXAErgtmQt/gzlFSN9j1jvr7vQgD4Z3/XKtxlW
  1858. 1Wke4Vth0v9js58AClGmcVXRa1rdkZ1GEoMSUsMLZB5VPrvFDTjtxRB8RQuQrgQRMrpGDYQqDsBX
  1859. mKx25KAnlqkpT4iIFF+5o8siwE8imRqAGg/22JUWg8Yud2wtaoXLnfVvUKiELMyLnfkbCjHI+NWN
  1860. QMlQeZ1cAyjGd9cGTQ6APty0eYEWyygf0AMYm5PVpK0+YCXyhxBRFEivclbDqv898EtHmrAePepC
  1861. S8VXAqUqBsf6HaTPC6hAI1et0Xdlmq4FccvHPwcB8T4Z9m1evvwb5S5hnIL4qGgC+k7/enpqJGPJ
  1862. ylei1zil8rc5xUeB1ipYhdw3STYN3+zpsb8z94XHXhocQhvD+aJ0AcOZh3hezKzlQpgWBONjk0AC
  1863. +t3p1JBtiNSVmO0ApaTetR09jBDdid1CK6CPx/2gvkizgwQ4M48pbPLqsGYQZG500QNwtRbcWi2q
  1864. LokDU7kh8wZKZ4z3iKRzQGtbQwu8z6DR2TlJOdwAcZ2MFd7ZGLCh88UnAIYb2NkBQFUgmBb7b9x6
  1865. lSqKkxPgfgJV8Nm4AqYbxYPq2nZPgZAF0XLtghJOlWvBN9nwwpPQ4SDlMdXc9x7bc8mvCwSXh153
  1866. JRW44NVOQWnnd/j6v4rxw5fbgLiY7r9g8hRQRR4ESGoQqHcpie42ap6d38wm/wIwBuVg
  1867. """)
  1868. ##file activate.sh
  1869. ACTIVATE_SH = convert("""
  1870. eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9
  1871. H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq
  1872. DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs
  1873. cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY
  1874. G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T
  1875. EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs
  1876. wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG
  1877. 5eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/
  1878. JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR
  1879. huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx
  1880. Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L
  1881. Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw
  1882. WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX
  1883. LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2
  1884. """)
  1885. ##file activate.fish
  1886. ACTIVATE_FISH = convert("""
  1887. eJydVm1v4jgQ/s6vmA1wBxUE7X2stJVYlVWR2lK13d6d9laRk0yIr8HmbIe0++tvnIQQB9pbXT5A
  1888. Ys/LM55nZtyHx5RrSHiGsMm1gRAh1xhDwU0Kng8hFzMWGb5jBv2E69SDs0TJDdj3MxilxmzPZzP7
  1889. pVPMMl+q9bjXh1eZQ8SEkAZULoAbiLnCyGSvvV6SC7IoBcS4Nw0wjcFbvJDcjiuTswzFDpiIQaHJ
  1890. lQAjQUi1YRmUboC2uZJig8J4PaCnT5IaDcgsbm/CjinOwgx1KcUTMEhhTgV4g2B1fRk8Le8fv86v
  1891. g7v545UHpZB9rKnp+gXsMhxLunIIpwVQxP/l9c/Hq9Xt1epm4R27bva6AJqN92G4YhbMG2i+LB+u
  1892. grv71c3dY7B6WtzfLy9bePbp0taDTXSwJQJszUnnp0y57mvpPcrF7ZODyhswtd59+/jdgw+fwBNS
  1893. xLSscksUPIDqwwNmCez3PpxGeyBYg6HE0YdcWBxcKczYzuVJi5Wu915vn5oWePCCoPUZBN5B7IgV
  1894. MCi54ZDLG7TUZ0HweXkb3M5vFmSpFm/gthhBx0UrveoPpv9AJ9unIbQYdUoe21bKg2q48sPFGVwu
  1895. H+afrxd1qvclaNlRFyh1EQ2sSccEuNAGWQwysfVpz1tPajUqbqJUnEcIJkWo6OXDaodK8ZiLdbmM
  1896. L1wb+9H0D+pcyPSrX5u5kgWSygRYXCnJUi/KKcuU4cqsAyTKZBiissLc7NFwizvjxtieKBVCIdWz
  1897. fzilzPaYyljZN0cGN1v7NnaIPNCGmVy3GKuJaQ6iVjE1Qfm+36hglErwmnAD8hu0dDy4uICBA8ZV
  1898. pQr/q/+O0KFW2kjelu9Dgb9SDBsWV4F4x5CswgS0zBVlk5tDMP5bVtUGpslbm81Lu2sdKq7uNMGh
  1899. MVQ4fy9xhogC1lS5guhISa0DlBWv0O8odT6/LP+4WZzDV6FzIkEqC0uolGZSZoMnlpxplmD2euaT
  1900. O4hkTpPnbztDccey0bhjDaBIqaWQa0uwEtQEwtyU56i4fq54F9IE3ORR6mKriODM4XOYZwaVYLYz
  1901. 7SPbKkz4i7VkB6/Ot1upDE3znNqYKpM8raa0Bx8vfvntJ32UENsM4aI6gJL+jJwhxhh3jVIDOcpi
  1902. m0r2hmEtS8XXXNBk71QCDXTBNhhPiHX2LtHkrVIlhoEshH/EZgdq53Eirqs5iFKMnkOmqZTtr3Xq
  1903. djvPTWZT4S3NT5aVLgurMPUWI07BRVYqkQrmtCKohNY8qu9EdACoT6ki0a66XxVF4f9AQ3W38yO5
  1904. mWmZmIIpnDFrbXakvKWeZhLwhvrbUH8fahhqD0YUcBDJjEBMQwiznE4y5QbHrbhHBOnUAYzb2tVN
  1905. jJa65e+eE2Ya30E2GurxUP8ssA6e/wOnvo3V78d3vTcvMB3n7l3iX1JXWqk=
  1906. """)
  1907. ##file activate.csh
  1908. ACTIVATE_CSH = convert("""
  1909. eJx9U11vmzAUffevOCVRu+UB9pws29Kl0iq1aVWllaZlcgxciiViItsQdb9+xiQp+dh4QOB7Pu49
  1910. XHqY59IgkwVhVRmLmFAZSrGRNkdgykonhFiqSCRW1sJSmJg8wCDT5QrucRCyHn6WFRKhVGmhKwVp
  1911. kUpNiS3emup3TY6XIn7DVNQyJUwlrgthJD6n/iCNv72uhCzCpFx9CRkThRQGKe08cWXJ9db/yh/u
  1912. pvzl9mn+PLnjj5P5D1yM8QmXlzBkSdXwZ0H/BBc0mEo5FE5qI2jKhclHOOvy9HD/OO/6YO1mX9vx
  1913. sY0H/tPIV0dtqel0V7iZvWyNg8XFcBA0ToEqVeqOdNUEQFvN41SumAv32VtJrakQNSmLWmgp4oJM
  1914. yDoBHgoydtoEAs47r5wHHnUal5vbJ8oOI+9wI86vb2d8Nrm/4Xy4RZ8R85E4uTZPB5EZPnTaaAGu
  1915. E59J8BE2J8XgrkbLeXMlVoQxznEYFYY8uFFdxsKQRx90Giwx9vSueHP1YNaUSFG4vTaErNSYuBOF
  1916. lXiVyXa9Sy3JdClEyK1dD6Nos9mEf8iKlOpmqSNTZnYjNEWiUYn2pKNB3ttcLJ3HmYYXy6Un76f7
  1917. r8rRsC1TpTJj7f19m5sUf/V3Ir+x/yjtLu8KjLX/CmN/AcVGUUo=
  1918. """)
  1919. ##file activate.bat
  1920. ACTIVATE_BAT = convert("""
  1921. eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8
  1922. qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug
  1923. sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU
  1924. ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu
  1925. """)
  1926. ##file deactivate.bat
  1927. DEACTIVATE_BAT = convert("""
  1928. eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q
  1929. FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL
  1930. i2dASrm4rFz9XLgAwJNbyQ==
  1931. """)
  1932. ##file activate.ps1
  1933. ACTIVATE_PS = convert("""
  1934. eJylWdmS40Z2fVeE/oHT6rCloNUEAXDThB6wAyQAEjsB29GBjdgXYiWgmC/zgz/Jv+AEWNVd3S2N
  1935. xuOKYEUxM+/Jmzfvcm7W//zXf/+wUMOoXtyi1F9kbd0sHH/hFc2iLtrK9b3FrSqyxaVQwr8uhqJd
  1936. uHaeg9mqzRdR8/13Pyy8qPLdJh0+LMhi0QCoXxYfFh9WtttEnd34H8p6/f1300KauwrULws39e18
  1937. 0ZaLNm9rgN/ZVf3h++/e124Vlc0vKsspHy+Yyi5+XbzPhijvCtduoiL/kA1ukWV27n0o7Sb8LIFj
  1938. CvWR5GQgUJdp1Pw8TS9+rPy6SDv/+e3d+0+4qw8f3v20+PliV37efEYBAB9FTKC+RHn/Cfxn3rdv
  1939. 00Fube5O+iyCtHDs9BfPfz3q4sfFv9d91Ljhfy7ei0VO+nVTtdOkv/jpt0l2AX6iG1jXgKnnDuD4
  1940. ke2k/i8fzzz5UedkVcP4pwF+Wvz2FJl+3vt598urXf5Y6LNA5WcFOP7r0sW7b9a+W/xcu0Xpv5zk
  1941. Kfq3P9Dz9di/fCxS72MXVU1rpx9L4Bxl85Wmn5a+zP76Zuh3pL9ROWr87PN+//GHIl+oOtvn9XSU
  1942. qH+p0gQBFnx1uV+JLH5O5zv+PXW+WepXVVHZT0+oQezkIATcIm+ivPV/z5J/+cYj3ir4w0Lx09vC
  1943. e5n/y5/Y5LPPfdrqb88ga/PabxZRVfmp39l588m/6u+/e+OpP+dF7n1WZpJ9//Z4v372fDDz9eHB
  1944. 7Juvs/BLMHzrxL9+9twXpJfhd1/DrpQ5Euu/vlss3wp9HXC/54C/Ld69m6zwdx3tC0d8daSv0V8B
  1945. n4b9YYF53sJelJV/ix6LZspw/sJtqyl5LJ5r/23htA1Imfm/gt9R7dqVB1LjhydAX4Gb+zksQF59
  1946. 9+P7H//U+376afFuvh2/T6P85Xr/5c8C6OXyFY4BGuN+EE0+GeR201b+wkkLN5mmBY5TfMw8ngqL
  1947. CztXxCSXKMCYrRIElWkEJlEPYsSOeKBVZCAQTKBhApMwRFQzmCThE0YQu2CdEhgjbgmk9GluHpfR
  1948. /hhwJCZhGI5jt5FsAkOrObVyE6g2y1snyhMGFlDY1x+BoHpCMulTj5JYWNAYJmnKpvLxXgmQ8az1
  1949. 4fUGxxcitMbbhDFcsiAItg04E+OSBIHTUYD1HI4FHH4kMREPknuYRMyhh3AARWMkfhCketqD1CWJ
  1950. mTCo/nhUScoQcInB1hpFhIKoIXLo5jLpwFCgsnLCx1QlEMlz/iFEGqzH3vWYcpRcThgWnEKm0QcS
  1951. rA8ek2a2IYYeowUanOZOlrbWSJUC4c7y2EMI3uJPMnMF/SSXdk6E495VLhzkWHps0rOhKwqk+xBI
  1952. DhJirhdUCTamMfXz2Hy303hM4DFJ8QL21BcPBULR+gcdYxoeiDqOFSqpi5B5PUISfGg46gFZBPo4
  1953. jdh8lueaWuVSMTURfbAUnLINr/QYuuYoMQV6l1aWxuZVTjlaLC14UzqZ+ziTGDzJzhiYoPLrt3uI
  1954. tXkVR47kAo09lo5BD76CH51cTt1snVpMOttLhY93yxChCQPI4OBecS7++h4p4Bdn4H97bJongtPk
  1955. s9gQnXku1vzsjjmX4/o4YUDkXkjHwDg5FXozU0fW4y5kyeYW0uJWlh536BKr0kMGjtzTkng6Ep62
  1956. uTWnQtiIqKnEsx7e1hLtzlXs7Upw9TwEnp0t9yzCGgUJIZConx9OHJArLkRYW0dW42G9OeR5Nzwk
  1957. yk1mX7du5RGHT7dka7N3AznmSif7y6tuKe2N1Al/1TUPRqH6E2GLVc27h9IptMLkCKQYRqPQJgzV
  1958. 2m6WLsSipS3v3b1/WmXEYY1meLEVIU/arOGVkyie7ZsH05ZKpjFW4cpY0YkjySpSExNG2TS8nnJx
  1959. nrQmWh2WY3cP1eISP9wbaVK35ZXc60yC3VN/j9n7UFoK6zvjSTE2+Pvz6Mx322rnftfP8Y0XKIdv
  1960. Qd7AfK0nexBTMqRiErvCMa3Hegpfjdh58glW2oNMsKeAX8x6YJLZs9K8/ozjJkWL+JmECMvhQ54x
  1961. 9rsTHwcoGrDi6Y4I+H7yY4/rJVPAbYymUH7C2D3uiUS3KQ1nrCAUkE1dJMneDQIJMQQx5SONxoEO
  1962. OEn1/Ig1eBBUeEDRuOT2WGGGE4bNypBLFh2PeIg3bEbg44PHiqNDbGIQm50LW6MJU62JHCGBrmc9
  1963. 2F7WBJrrj1ssnTAK4sxwRgh5LLblhwNAclv3Gd+jC/etCfyfR8TMhcWQz8TBIbG8IIyAQ81w2n/C
  1964. mHWAwRzxd3WoBY7BZnsqGOWrOCKwGkMMNfO0Kci/joZgEocLjNnzgcmdehPHJY0FudXgsr+v44TB
  1965. I3jnMGnsK5veAhgi9iXGifkHMOC09Rh9cAw9sQ0asl6wKMk8mpzFYaaDSgG4F0wisQDDBRpjCINg
  1966. FIxhlhQ31xdSkkk6odXZFpTYOQpOOgw9ugM2cDQ+2MYa7JsEirGBrOuxsQy5nPMRdYjsTJ/j1iNw
  1967. FeSt1jY2+dd5yx1/pzZMOQXUIDcXeAzR7QlDRM8AMkUldXOmGmvYXPABjxqkYKO7VAY6JRU7kpXr
  1968. +Epu2BU3qFFXClFi27784LrDZsJwbNlDw0JzhZ6M0SMXE4iBHehCpHVkrQhpTFn2dsvsZYkiPEEB
  1969. GSEAwdiur9LS1U6P2U9JhGp4hnFpJo4FfkdJHcwV6Q5dV1Q9uNeeu7rV8PAjwdFg9RLtroifOr0k
  1970. uOiRTo/obNPhQIf42Fr4mtThWoSjitEdAmFW66UCe8WFjPk1YVNpL9srFbond7jrLg8tqAasIMpy
  1971. zkH0SY/6zVAwJrEc14zt14YRXdY+fcJ4qOd2XKB0/Kghw1ovd11t2o+zjt+txndo1ZDZ2T+uMVHT
  1972. VSXhedBAHoJIID9xm6wPQI3cXY+HR7vxtrJuCKh6kbXaW5KkVeJsdsjqsYsOwYSh0w5sMbu7LF8J
  1973. 5T7U6LJdiTx+ca7RKlulGgS5Z1JSU2Llt32cHFipkaurtBrvNX5UtvNZjkufZ/r1/XyLl6yOpytL
  1974. Km8Fn+y4wkhlqZP5db0rooqy7xdL4wxzFVTX+6HaxuQJK5E5B1neSSovZ9ALB8091dDbbjVxhWNY
  1975. Ve5hn1VnI9OF0wpvaRm7SZuC1IRczwC7GnkhPt3muHV1YxUJfo+uh1sYnJy+vI0ZwuPV2uqWJYUH
  1976. bmBsi1zmFSxHrqwA+WIzLrHkwW4r+bad7xbOzJCnKIa3S3YvrzEBK1Dc0emzJW+SqysQfdEDorQG
  1977. 9ZJlbQzEHQV8naPaF440YXzJk/7vHGK2xwuP+Gc5xITxyiP+WQ4x18oXHjFzCBy9kir1EFTAm0Zq
  1978. LYwS8MpiGhtfxiBRDXpxDWxk9g9Q2fzPPAhS6VFDAc/aiNGatUkPtZIStZFQ1qD0IlJa/5ZPAi5J
  1979. ySp1ETDomZMnvgiysZSBfMikrSDte/K5lqV6iwC5q7YN9I1dBZXUytDJNqU74MJsUyNNLAPopWK3
  1980. tzmLkCiDyl7WQnj9sm7Kd5kzgpoccdNeMw/6zPVB3pUwMgi4C7hj4AMFAf4G27oXH8NNT9zll/sK
  1981. S6wVlQwazjxWKWy20ZzXb9ne8ngGalPBWSUSj9xkc1drsXkZ8oOyvYT3e0rnYsGwx85xZB9wKeKg
  1982. cJKZnamYwiaMymZvzk6wtDUkxmdUg0mPad0YHtvzpjEfp2iMxvORhnx0kCVLf5Qa43WJsVoyfEyI
  1983. pzmf8ruM6xBr7dnBgzyxpqXuUPYaKahOaz1LrxNkS/Q3Ae5AC+xl6NbxAqXXlzghZBZHmOrM6Y6Y
  1984. ctAkltwlF7SKEsShjVh7QHuxMU0a08/eiu3x3M+07OijMcKFFltByXrpk8w+JNnZpnp3CfgjV1Ax
  1985. gUYCnWwYow42I5wHCcTzLXK0hMZN2DrPM/zCSqe9jRSlJnr70BPE4+zrwbk/xVIDHy2FAQyHoomT
  1986. Tt5jiM68nBQut35Y0qLclLiQrutxt/c0OlSqXAC8VrxW97lGoRWzhOnifE2zbF05W4xuyhg7JTUL
  1987. aqJ7SWDywhjlal0b+NLTpERBgnPW0+Nw99X2Ws72gOL27iER9jgzj7Uu09JaZ3n+hmCjjvZpjNst
  1988. vOWWTbuLrg+/1ltX8WpPauEDEvcunIgTxuMEHweWKCx2KQ9DU/UKdO/3za4Szm2iHYL+ss9AAttm
  1989. gZHq2pkUXFbV+FiJCKrpBms18zH75vax5jSo7FNunrVWY3Chvd8KKnHdaTt/6ealwaA1x17yTlft
  1990. 8VBle3nAE+7R0MScC3MJofNCCkA9PGKBgGMYEwfB2QO5j8zUqa8F/EkWKCzGQJ5EZ05HTly1B01E
  1991. z813G5BY++RZ2sxbQS8ZveGPJNabp5kXAeoign6Tlt5+L8i5ZquY9+S+KEUHkmYMRFBxRrHnbl2X
  1992. rVemKnG+oB1yd9+zT+4c43jQ0wWmQRR6mTCkY1q3VG05Y120ZzKOMBe6Vy7I5Vz4ygPB3yY4G0FP
  1993. 8RxiMx985YJPXsgRU58EuHj75gygTzejP+W/zKGe78UQN3yOJ1aMQV9hFH+GAfLRsza84WlPLAI/
  1994. 9G/5JdcHftEfH+Y3/fHUG7/o8bv98dzzy3e8S+XCvgqB+VUf7sH0yDHpONdbRE8tAg9NWOzcTJ7q
  1995. TuAxe/AJ07c1Rs9okJvl1/0G60qvbdDzz5zO0FuPFQIHNp9y9Bd1CufYVx7dB26mAxwa8GMNrN/U
  1996. oGbNZ3EQ7inLzHy5tRg9AXJrN8cB59cCUBeCiVO7zKM0jU0MamhnRThkg/NMmBOGb6StNeD9tDfA
  1997. 7czsAWopDdnGoXUHtA+s/k0vNPkBcxEI13jVd/axp85va3LpwGggXXWw12Gwr/JGAH0b8CPboiZd
  1998. QO1l0mk/UHukud4C+w5uRoNzpCmoW6GbgbMyaQNkga2pQINB18lOXOCJzSWPFOhZcwzdgrsQnne7
  1999. nvjBi+7cP2BbtBeDOW5uOLGf3z94FasKIguOqJl+8ss/6Kumns4cuWbqq5592TN/RNIbn5Qo6qbi
  2000. O4F0P9txxPAwagqPlftztO8cWBzdN/jz3b7GD6JHYP/Zp4ToAMaA74M+EGSft3hEGMuf8EwjnTk/
  2001. nz/P7SLipB/ogQ6xNX0fDqNncMCfHqGLCMM0ZzFa+6lPJYQ5p81vW4HkCvidYf6kb+P/oB965g8K
  2002. C6uR0rdjX1DNKc5pOSTquI8uQ6KXxYaKBn+30/09tK4kMpJPgUIQkbENEPbuezNPPje2Um83SgyX
  2003. GTCJb6MnGVIpgncdQg1qz2bvPfxYD9fewCXDomx9S+HQJuX6W3VAL+v5WZMudRQZk9ZdOk6GIUtC
  2004. PqEb/uwSIrtR7/edzqgEdtpEwq7p2J5OQV+RLrmtTvFwFpf03M/VrRyTZ73qVod7v7Jh2Dwe5J25
  2005. JqFOU2qEu1sP+CRotklediycKfLjeIZzjJQsvKmiGSNQhxuJpKa+hoWUizaE1PuIRGzJqropwgVB
  2006. oo1hr870MZLgnXF5ZIpr6mF0L8aSy2gVnTAuoB4WEd4d5NPVC9TMotYXERKlTcwQ2KiB/C48AEfH
  2007. Qbyq4CN8xTFnTvf/ebOc3isnjD95s0QF0nx9s+y+zMmz782xL0SgEmRpA3x1w1Ff9/74xcxKEPdS
  2008. IEFTz6GgU0+BK/UZ5Gwbl4gZwycxEw+Kqa5QmMkh4OzgzEVPnDAiAOGBFaBW4wkDmj1G4RyElKgj
  2009. NlLCq8zsp085MNh/+R4t1Q8yxoSv8PUpTt7izZwf2BTHZZ3pIZpUIpuLkL1nNL6sYcHqcKm237wp
  2010. T2+RCjgXweXd2Zp7ZM8W6dG5bZsqo0nrJBTx8EC0+CQQdzEGnabTnkzofu1pYkWl4E7XSniECdxy
  2011. vLYavPMcL9LW5SToJFNnos+uqweOHriUZ1ntIYZUonc7ltEQ6oTRtwOHNwez2sVREskHN+bqG3ua
  2012. eaEbJ8XpyO8CeD9QJc8nbLP2C2R3A437ISUNyt5Yd0TbDNcl11/DSsOzdbi/VhCC0KE6v1vqVNkq
  2013. 45ZnG6fiV2NwzInxCNth3BwL0+8814jE6+1W1EeWtpWbSZJOJNYXmWRXa7vLnAljE692eHjZ4y5u
  2014. y1u63De0IzKca7As48Z3XshVF+3XiLNz0JIMh/JOpbiNLlMi672uO0wYzOCZjRxcxj3D+gVenGIE
  2015. MvFUGGXuRps2RzMcgWIRolHXpGUP6sMsQt1hspUBnVKUn/WQj2u6j3SXd9Xz0QtEzoM7qTu5y7gR
  2016. q9gNNsrlEMLdikBt9bFvBnfbUIh6voTw7eDsyTmPKUvF0bHqWLbHe3VRHyRZnNeSGKsB73q66Vsk
  2017. taxWYmwz1tYVFG/vOQhlM0gUkyvIab3nv2caJ1udU1F3pDMty7stubTE4OJqm0i0ECfrJIkLtraC
  2018. HwRWKzlqpfhEIqYH09eT9WrOhQyt8YEoyBlnXtAT37WHIQ03TIuEHbnRxZDdLun0iok9PUC79prU
  2019. m5beZzfQUelEXnhzb/pIROKx3F7qCttYIFGh5dXNzFzID7u8vKykA8Uejf7XXz//S4nKvW//ofS/
  2020. QastYw==
  2021. """)
  2022. ##file distutils-init.py
  2023. DISTUTILS_INIT = convert("""
  2024. eJytV92L4zYQf/dfMU0ottuse7RvC6FQrg8Lxz2Ugz4si9HacqKuIxlJ2ST313dG8odkO9d7aGBB
  2025. luZLv/nNjFacOqUtKJMIvzK3cXlhWgp5MDBsqK5SNYftsBAGpLLA4F1oe2Ytl+9wUvW55TswCi4c
  2026. KibhbFDSglXQCFmDPXIwtm7FawLRbwtPzg2T9gf4gupKv4GS0N262w7V0NvpbCy8cvTo3eAus6C5
  2027. ETU3ICQZX1hFTw/dzR6V/AW1RCN4/XAtbsVXqIXmlVX6liS4lOzEYY9QFB2zx6LfoSNjz1a0pqT9
  2028. QOIfJWQ2E888NEVZNqLlZZnvIB0NpHkimlFdKn2iRRY7yGG/CCJb6Iz280d34SFXBS2yEYPNF0Q7
  2029. yM7oCjpWvbEDQmnhRwOs6zjThpKE8HogwRAgraqYFZgGZvzmzVh+mgz9vskT3hruwyjdFcqyENJw
  2030. bbMPO5jdzonxK68QKT7B57CMRRG5shRSWDTX3dI8LzRndZbnSWL1zfvriUmK4TcGWSnZiEPCrxXv
  2031. bM+sP7VW2is2WgWXCO3sAu3Rzysz3FiNCA8WPyM4gb1JAAmCiyTZbhFjWx3h9SzauuRXC9MFoVbc
  2032. yNTCm1QXOOIfIn/g1kGMhDUBN72hI5XCBQtIXQw8UEEdma6Jaz4vJIJ51Orc15hzzmu6TdFp3ogr
  2033. Aof0c98tsw1SiaiWotHffk3XYCkqdToxWRfTFXqgpg2khcLluOHMVC0zZhLKIomesfSreUNNgbXi
  2034. Ky9VRzwzkBneNoGQyyvGjbsFQqOZvpWIjqH281lJ/jireFgR3cPzSyTGWzQpDNIU+03Fs4XKLkhp
  2035. /n0uFnuF6VphB44b3uWRneSbBoMSioqE8oeF0JY+qTvYfEK+bPLYdoR4McfYQ7wMZj39q0kfP8q+
  2036. FfsymO0GzNlPh644Jje06ulqHpOEQqdJUfoidI2O4CWx4qOglLye6RrFQirpCRXvhoRqXH3sYdVJ
  2037. AItvc+VUsLO2v2hVAWrNIfVGtkG351cUMNncbh/WdowtSPtCdkzYFv6mwYc9o2Jt68ud6wectBr8
  2038. hYAulPSlgzH44YbV3ikjrulEaNJxt+/H3wZ7bXSXje/YY4tfVVrVmUstaDwwOBLMg6iduDB0lMVC
  2039. UyzYx7Ab4kjCqdViEJmDcdk/SKbgsjYXgfMznUWcrtS4z4fmJ/XOM1LPk/iIpqass5XwNbdnLb1Y
  2040. 8h3ERXSWZI6rZJxKs1LBqVH65w0Oy4ra0CBYxEeuOMbDmV5GI6E0Ha/wgVTtkX0+OXvqsD02CKLf
  2041. XHbeft85D7tTCMYy2Njp4DJP7gWJr6paVWXZ1+/6YXLv/iE0M90FktiI7yFJD9e7SOLhEkkaMTUO
  2042. azq9i2woBNR0/0eoF1HFMf0H8ChxH/jgcB34GZIz3Qn4/vid+VEamQrOVqAPTrOfmD4MPdVh09tb
  2043. 8dLLjvh/61lEP4yW5vJaH4vHcevG8agXvzPGoOhhXNncpTr99PTHx6e/UvffFLaxUSjuSeP286Dw
  2044. gtEMcW1xKr/he4/6IQ6FUXP+0gkioHY5iwC9Eyx3HKO7af0zPPe+XyLn7fAY78k4aiR387bCr5XT
  2045. 5C4rFgwLGfMvJuAMew==
  2046. """)
  2047. ##file distutils.cfg
  2048. DISTUTILS_CFG = convert("""
  2049. eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  2050. xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
  2051. 9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
  2052. """)
  2053. ##file activate_this.py
  2054. ACTIVATE_THIS = convert("""
  2055. eJyNU01v2zAMvetXEB4K21jmDOstQA4dMGCHbeihlyEIDMWmG62yJEiKE//7kXKdpN2KzYBt8euR
  2056. fKSyLPs8wiEo8wh4wqZTGou4V6Hm0wJa1cSiTkJdr8+GsoTRHuCotBayiWqQEYGtMCgfD1KjGYBe
  2057. 5a3p0cRKiAe2NtLADikftnDco0ko/SFEVgEZ8aRC5GLux7i3BpSJ6J1H+i7A2CjiHq9z7JRZuuQq
  2058. siwTIvpxJYCeuWaBpwZdhB+yxy/eWz+ZvVSU8C4E9FFZkyxFsvCT/ZzL8gcz9aXVE14Yyp2M+2W0
  2059. y7n5mp0qN+avKXvbsyyzUqjeWR8hjGE+2iCE1W1tQ82hsCZN9UzlJr+/e/iab8WfqsmPI6pWeUPd
  2060. FrMsd4H/55poeO9n54COhUs+sZNEzNtg/wanpjpuqHJaxs76HtZryI/K3H7KJ/KDIhqcbJ7kI4ar
  2061. XL+sMgXnX0D+Te2Iy5xdP8yueSlQB/x/ED2BTAtyE3K4SYUN6AMNfbO63f4lBW3bUJPbTL+mjSxS
  2062. PyRfJkZRgj+VbFv+EzHFi5pKwUEepa4JslMnwkowSRCXI+m5XvEOvtuBrxHdhLalG0JofYBok6qj
  2063. YdN2dEngUlbC4PG60M1WEN0piu7Nq7on0mgyyUw3iV1etLo6r/81biWdQ9MWHFaePWZYaq+nmp+t
  2064. s3az+sj7eA0jfgPfeoN1
  2065. """)
  2066. if __name__ == '__main__':
  2067. main()
  2068. ## TODO:
  2069. ## Copy python.exe.manifest
  2070. ## Monkeypatch distutils.sysconfig