<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>r2/r2/lib/cssfilter.py</filename>
    </added>
    <added>
      <filename>r2/r2/public/static/transpLOGO.png</filename>
    </added>
    <added>
      <filename>r2/r2/templates/cnameframe.html</filename>
    </added>
    <added>
      <filename>r2/r2/templates/csserror.html</filename>
    </added>
    <added>
      <filename>r2/r2/templates/subredditstylesheet.html</filename>
    </added>
    <added>
      <filename>r2/r2/templates/uploadedimage.html</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -14,6 +14,7 @@
 .hgignore
 lighttpd.**
 development.ini
+development_*.ini
 production.ini
 r2/r2/public/static/frame.js
 r2/r2/public/static/reddit.js</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -64,6 +64,8 @@ write_query_queue = False
 stylesheet = reddit.css
 stylesheet_rtl = reddit_rtl.css
 
+allowed_css_linked_domains = my.domain.com, my.otherdomain.com
+
 login_cookie = reddit_session
 domain = localhost
 default_sr = localhost</diff>
      <filename>r2/example.ini</filename>
    </modified>
    <modified>
      <diff>@@ -173,11 +173,24 @@ class DomainMiddleware(object):
     def __call__(self, environ, start_response):
         # get base domain as defined in INI file
         base_domain = config['global_conf']['domain']
-
-        sub_domains = environ['HTTP_HOST']
-        if not sub_domains.endswith(base_domain):
-            #if the domain doesn't end with base_domain, don't do anything
-            return self.app(environ, start_response)
+        try:
+            sub_domains, request_port  = environ['HTTP_HOST'].split(':')
+            environ['request_port'] = int(request_port)
+        except ValueError:
+            sub_domains  = environ['HTTP_HOST'].split(':')[0]
+            
+        #If the domain doesn't end with base_domain, assume
+        #this is a cname, and redirect to the frame controller.
+        #Ignore localhost so paster shell still works.
+        #If this is an error, don't redirect
+        if (not sub_domains.endswith(base_domain) 
+            and (not sub_domains == 'localhost')):
+            environ['sub_domain'] = sub_domains
+            if (not environ.get('extension') 
+                and (not environ['PATH_INFO'].startswith('/error'))):
+                environ['original_path'] = environ['PATH_INFO']
+                environ['PATH_INFO'] = '/frame'
+                return self.app(environ, start_response)
 
         sub_domains = sub_domains[:-len(base_domain)].strip('.')
         sub_domains = sub_domains.split('.')
@@ -294,6 +307,22 @@ class RequestLogMiddleware(object):
                 pass
         return r
 
+class LimitUploadSize(object):
+    def __init__(self, app, max_size=1024*500):
+        self.app = app
+        self.max_size = max_size
+
+    def __call__(self, environ, start_response):
+        cl_key = 'CONTENT_LENGTH'
+        if environ['REQUEST_METHOD'] == 'POST':
+            if ((cl_key not in environ)
+                or int(environ[cl_key]) &gt; self.max_size):
+                r = Response()
+                r.status_code = 500
+                r.content = 'request too big'
+                return r(environ, start_response)
+                
+        return self.app(environ, start_response)
 
 #god this shit is disorganized and confusing
 class RedditApp(PylonsBaseWSGIApp):
@@ -335,13 +364,15 @@ def make_app(global_conf, full_stack=True, **app_conf):
 
     # CUSTOM MIDDLEWARE HERE (filtered by the error handling middlewares)
 
+    app = LimitUploadSize(app)
     app = ProfilingMiddleware(app)
     app = SourceViewMiddleware(app)
 
-    app = DomainMiddleware(app)
     app = SubredditMiddleware(app)
+    app = DomainMiddleware(app)
     app = ExtensionMiddleware(app)
 
+
     log_path = global_conf.get('log_path')
     if log_path:
         process_iden = global_conf.get('scgi_port', 'default')</diff>
      <filename>r2/r2/config/middleware.py</filename>
    </modified>
    <modified>
      <diff>@@ -94,6 +94,8 @@ def make_map(global_conf={}, app_conf={}):
     
     mc('/mail/optout', controller='front', action = 'optout')
     mc('/mail/optin',  controller='front', action = 'optin')
+    mc('/stylesheet', controller = 'front', action = 'stylesheet')
+    mc('/frame', controller='front', action = 'frame')
 
     mc('/', controller='hot', action='listing')
     </diff>
      <filename>r2/r2/config/routing.py</filename>
    </modified>
    <modified>
      <diff>@@ -27,12 +27,13 @@ from pylons import c, request
 from validator import *
 
 from r2.models import *
+from r2.models.subreddit import Default as DefaultSR
 import r2.models.thing_changes as tc
 
 from r2.lib.utils import get_title, sanitize_url, timeuntil, set_last_modified
 from r2.lib.wrapped import Wrapped
 from r2.lib.pages import FriendList, ContributorList, ModList, \
-    BannedList, BoringPage, FormPage, NewLink
+    BannedList, BoringPage, FormPage, NewLink, CssError, UploadedImage
 
 from r2.lib.menus import CommentSortMenu
 from r2.lib.translation import Translator
@@ -40,15 +41,18 @@ from r2.lib.normalized_hot import expire_hot
 from r2.lib.captcha import get_iden
 from r2.lib import emailer
 from r2.lib.strings import strings
+from r2.lib.memoize import clear_memo
+from r2.lib.filters import _force_unicode
 from r2.lib.db import queries
 from r2.config import cache
-
-from simplejson import dumps
-
 from r2.lib.jsonresponse import JsonResponse, Json
 from r2.lib.jsontemplates import api_type
+from r2.lib import cssfilter
+
+from simplejson import dumps
 
 from datetime import datetime, timedelta
+from md5 import md5
 from r2.lib.organic import update_pos
 
 def link_listing_by_url(url, count = None):
@@ -64,7 +68,7 @@ def link_listing_by_url(url, count = None):
     builder = IDBuilder(names, num = 25)
     listing = LinkListing(builder).listing()
     return listing
-            
+
     
 class ApiController(RedditController):
     def response_func(self, **kw):
@@ -74,9 +78,9 @@ class ApiController(RedditController):
         try:    
             l = Link._by_url(url, sr)
             if message:
-                return l.permalink + '?already_submitted=true'
+                return l.already_submitted_link()
             else:
-                return l.permalink
+                return l.make_permalink_slow()
         except NotFound:
             pass
 
@@ -272,7 +276,7 @@ class ApiController(RedditController):
         # well, nothing left to do but submit it
         l = Link._submit(request.post.title, url, c.user, sr, ip, spam)
         if url.lower() == 'self':
-            l.url = l.permalink
+            l.url = l.make_permalink_slow()
             l.is_self = True
             l._commit()
         Vote.vote(c.user, l, True, ip, spam)
@@ -292,8 +296,16 @@ class ApiController(RedditController):
         
         # flag search indexer that something has changed
         tc.changed(l)
+        
+        # make_permalink is designed for links that can be set to _top
+        # here, we need to generate an ajax redirect as if we were not on a
+        # cname.
+        cname = c.cname
+        c.cname = False
+        path = l.make_permalink_slow()
+        c.cname = cname
 
-        res._redirect(l.permalink)
+        res._redirect(path)
 
 
     def _login(self, res, user, dest='', rem = None):
@@ -722,11 +734,115 @@ class ApiController(RedditController):
     @Json
     @validate(VUser(),
               VModhash(),
+              stylesheet_contents = nop('stylesheet_contents'),
+              op = VOneOf('op',['save','preview']))
+    def POST_subreddit_stylesheet(self, res, stylesheet_contents = '', op='save'):
+        if not c.site.can_change_stylesheet(c.user):
+            return self.abort(403,'forbidden')
+
+        if g.css_killswitch:
+            return self.abort(403,'forbidden')
+
+        parsed, report = cssfilter.validate_css(stylesheet_contents)
+
+        if report.errors:
+            error_items = [ CssError(x).render(style='html')
+                            for x in sorted(report.errors) ]
+                                               
+            res._update('status', innerHTML = _('validation errors'))
+            res._update('validation-errors', innerHTML = ''.join(error_items))
+            res._show('error-header')
+        else:
+            res._hide('error-header')
+            res._update('status', innerHTML = '')
+            res._update('validation-errors', innerHTML = '')
+
+        if not report.errors and op == 'save':
+            stylesheet_contents_user   = stylesheet_contents
+            stylesheet_contents_parsed = parsed.cssText if parsed else ''
+
+            c.site.stylesheet_contents      = stylesheet_contents_parsed
+            c.site.stylesheet_contents_user = stylesheet_contents_user
+
+            c.site.stylesheet_hash = md5(stylesheet_contents_parsed).hexdigest()
+
+            set_last_modified(c.site,'stylesheet_contents')
+            tc.changed(c.site)
+            c.site._commit()
+
+            res._update('status', innerHTML = 'saved')
+            res._call('applyStylesheetFromTextbox(&quot;stylesheet_contents&quot;);')
+            res._update('validation-errors', innerHTML = '')
+
+        elif op == 'preview':
+            # try to find a link to use, otherwise give up and
+            # return
+            links = cssfilter.find_preview_links(c.site)
+            if not links:
+                # we're probably not going to be able to find any
+                # comments, either; screw it
+                return
+
+            res._show('preview-table')
+
+            # do a regular link
+            cssfilter.rendered_link('preview_link_normal',
+                                    res, links,
+                                    media = 'off', compress=False)
+            # now do one with media
+            cssfilter.rendered_link('preview_link_media',
+                                    res, links,
+                                    media = 'on', compress=False)
+            # do a compressed link
+            cssfilter.rendered_link('preview_link_compressed',
+                                    res, links,
+                                    media = 'off', compress=True)
+            # and do a comment
+            comments = cssfilter.find_preview_comments(c.site)
+            if not comments:
+                return
+            cssfilter.rendered_comment('preview_comment',res,comments)
+
+    @validate(VUser(),
+              VModhash(),
+              VRatelimit(rate_user = True,
+                         rate_ip = True,
+                         prefix = 'upload_reddit_img_'),
+              file = VLength('file',length=1024*500),
+              op = VOneOf('op',['upload','delete']))
+    def POST_upload_header_img(self, file, op):
+        if not c.site.can_change_stylesheet(c.user):
+            return self.abort403()
+
+        if g.css_killswitch:
+            return self.abort(403,'forbidden')
+
+        if op == 'upload':
+            try:
+                cleaned = cssfilter.clean_image(file,'PNG')
+                new_url = cssfilter.save_header_image(c.site, cleaned)
+            except cssfilter.BadImage:
+                return UploadedImage(_('bad image'),c.site.header).render()
+
+            c.site.header = new_url
+            c.site._commit()
+
+            return UploadedImage(_('saved'),new_url,'upload').render()
+        elif op == 'delete':
+            c.site.header = None
+            c.site._commit()
+
+            return UploadedImage(_('deleted'),DefaultSR.header,'delete').render()
+
+    @Json
+    @validate(VUser(),
+              VModhash(),
               VRatelimit(rate_user = True,
                          rate_ip = True,
                          prefix = 'create_reddit_'),
               name = VSubredditName(&quot;name&quot;),
               title = VSubredditTitle(&quot;title&quot;),
+              domain = VCnameDomain(&quot;domain&quot;),
               description = VSubredditDesc(&quot;description&quot;),
               firsttext = nop(&quot;firsttext&quot;),
               header = nop(&quot;headerfile&quot;),
@@ -740,11 +856,10 @@ class ApiController(RedditController):
               type = VOneOf('type', ('public', 'private', 'restricted'))
               )
     def POST_site_admin(self, res, name ='', sr = None, **kw):
-        res._update('status', innerHTML = '')
         redir = False
         kw = dict((k, v) for k, v in kw.iteritems()
                   if v is not None
-                  and k in ('name', 'title', 'description', 'firsttext',
+                  and k in ('name', 'title', 'domain', 'description', 'firsttext',
                             'static_path', 'ad_file', 'over_18', 'show_media',
                             'type', 'header', 'lang', 'stylesheet'))
 
@@ -753,6 +868,12 @@ class ApiController(RedditController):
             time = timeuntil(datetime.now(g.tz) + timedelta(seconds=600))
             c.errors.add(errors.RATELIMIT, {'time': time})
 
+        domain = kw['domain']
+        cname_sr = domain and Subreddit._by_domain(domain)
+        if cname_sr and (not sr or sr != cname_sr):
+                kw['domain'] = None
+                c.errors.add(errors.USED_CNAME)
+
         if not sr and res._chk_error(errors.RATELIMIT):
             pass
         elif not sr and res._chk_errors((errors.SUBREDDIT_EXISTS,
@@ -764,6 +885,9 @@ class ApiController(RedditController):
             res._focus('title')
         elif res._chk_error(errors.INVALID_SUBREDDIT_TYPE):
             pass
+        elif res._chk_errors((errors.BAD_CNAME, errors.USED_CNAME)):
+            res._hide('example_domain')
+            res._focus('domain')
         elif res._chk_error(errors.DESC_TOO_LONG):
             res._focus('description')
 
@@ -784,6 +908,7 @@ class ApiController(RedditController):
 
         if not res.error:
             #assume sr existed, or was just built
+            clear_memo('subreddit._by_domain', Subreddit, _force_unicode(sr.domain))
             for k, v in kw.iteritems():
                 setattr(sr, k, v)
             sr._commit()
@@ -791,6 +916,9 @@ class ApiController(RedditController):
             # flag search indexer that something has changed
             tc.changed(sr)
 
+            res._update('status', innerHTML = _('saved'))
+
+
         if redir:
             res._redirect(redir)
 </diff>
      <filename>r2/r2/controllers/api.py</filename>
    </modified>
    <modified>
      <diff>@@ -98,8 +98,13 @@ class ErrorController(RedditController):
         try:
             return RedditController.__call__(self, environ, start_response)
         except:
-            c.response.content = &quot;something really awful just happened&quot;
-            return c.response
+            if g.debug:
+                # if we're in debug mode, let this hit Pylons so we
+                # get a stack trace
+                raise
+            else:
+                c.response.content = &quot;something really awful just happened&quot;
+                return c.response
 
 
     def send403(self):</diff>
      <filename>r2/r2/controllers/error.py</filename>
    </modified>
    <modified>
      <diff>@@ -57,6 +57,8 @@ error_list = dict((
         ('DRACONIAN', _('you must accept the terms first')),
         ('BANNED_IP', &quot;IP banned&quot;),
         ('BANNED_DOMAIN', &quot;Domain banned&quot;),
+        ('BAD_CNAME', &quot;that domain isn't going to work&quot;),
+        ('USED_CNAME', &quot;that cname is already in use&quot;),
         ('INVALID_SUBREDDIT_TYPE', _('that option is not valid')),
         ('DESC_TOO_LONG', _('description is too long')),
         ('CHEATER', 'what do you think you\'re doing there?'),</diff>
      <filename>r2/r2/controllers/errors.py</filename>
    </modified>
    <modified>
      <diff>@@ -154,7 +154,7 @@ class FrontController(RedditController):
 
         # if permalink page, add that message first to the content
         if comment:
-            displayPane.append(PermalinkMessage(article.permalink))
+            displayPane.append(PermalinkMessage(article.make_permalink_slow()))
 
         # insert reply box only for logged in user
         if c.user_is_loggedin and article.subreddit_slow.can_comment(c.user):
@@ -328,10 +328,21 @@ class FrontController(RedditController):
                        ).render()
         return res
 
+    def GET_stylesheet(self):
+        if hasattr(c.site,'stylesheet_contents') and not g.css_killswitch:
+            self.check_modified(c.site,'stylesheet_contents')
+
+            c.response.content = c.site.stylesheet_contents
+            c.response_content_type = 'text/css'
+
+            return c.response
+        else:
+            return self.abort404()
+
     @base_listing
     @validate(location = nop('location'))
     def GET_editreddit(self, location, num, after, reverse, count):
-        &quot;&quot;&quot;Edit reddit form. &quot;&quot;&quot;
+        &quot;&quot;&quot;Edit reddit form.&quot;&quot;&quot;
         if isinstance(c.site, FakeSubreddit):
             return self.abort404()
 
@@ -346,6 +357,17 @@ class FrontController(RedditController):
             pane = BannedList(editable = is_moderator)
         elif location == 'contributors' and c.site.type != 'public':
             pane = ContributorList(editable = is_moderator)
+        elif (location == 'stylesheet'
+              and c.site.can_change_stylesheet(c.user)
+              and not g.css_killswitch):
+            if hasattr(c.site,'stylesheet_contents_user') and c.site.stylesheet_contents_user:
+                stylesheet_contents = c.site.stylesheet_contents_user
+            elif hasattr(c.site,'stylesheet_contents') and c.site.stylesheet_contents:
+                stylesheet_contents = c.site.stylesheet_contents
+            else:
+                stylesheet_contents = ''
+            pane = SubredditStylesheet(site = c.site,
+                                       stylesheet_contents = stylesheet_contents)
         elif is_moderator and location == 'spam':
             links = Link._query(Link.c._spam == True)
             comments = Comment._query(Comment.c._spam == True)
@@ -486,6 +508,10 @@ class FrontController(RedditController):
         &quot;&quot;&quot;wipe login cookie and redirect to referer.&quot;&quot;&quot;
         self.logout()
         dest = request.referer or '/'
+        if c.cname:
+            dest = '/?cnameframe=1'
+        if not dest.startswith(&quot;http://&quot;):
+            return self.redirect(c.site.path + dest)
         return self.redirect(dest)
 
     
@@ -591,3 +617,14 @@ class FrontController(RedditController):
         ApiController.POST_optin.&quot;&quot;&quot;
         return self._render_opt_in_out(msg_hash, False)
     
+    def GET_frame(self):
+        &quot;&quot;&quot;used for cname support.  makes a frame and
+        puts the proper url as the frame source&quot;&quot;&quot;
+        sub_domain = request.environ.get('sub_domain')
+        original_path = request.environ.get('original_path')
+        sr = Subreddit._by_domain(sub_domain)
+        if sub_domain and sr and original_path:
+            return Cnameframe(original_path, sr.name, sr.title, sub_domain).render()
+        else:
+            return self.abort404()
+</diff>
      <filename>r2/r2/controllers/front.py</filename>
    </modified>
    <modified>
      <diff>@@ -350,7 +350,7 @@ class MessageController(ListingController):
     @staticmethod
     def builder_wrapper(thing):
         if isinstance(thing, Comment):
-            p = thing.permalink
+            p = thing.make_permalink_slow()
             f = thing._fullname
             thing.__class__ = Message
             w = Wrapped(thing)</diff>
      <filename>r2/r2/controllers/listingcontroller.py</filename>
    </modified>
    <modified>
      <diff>@@ -101,10 +101,14 @@ class PostController(ApiController):
               pref_min_comment_score = VInt('min_comment_score', -100, 100),
               pref_num_comments = VInt('num_comments', 1, g.max_comments,
                                        default = g.num_comments),
+              pref_show_stylesheets = VBoolean('show_stylesheets'),
               all_langs = nop('all-langs', default = 'all'))
     def POST_options(self, all_langs, pref_lang, **kw):
         self.set_options(all_langs, pref_lang, **kw)
-        return self.redirect(&quot;/prefs?done=true&quot;)
+        q_string = {'done': 'true'}
+        if c.cname:
+            q_string['cnameframe'] = '1'
+        return self.redirect((request.referer or &quot;/prefs&quot;) + query_string(q_string))
             
     def GET_over18(self):
         return BoringPage(_(&quot;over 18?&quot;),</diff>
      <filename>r2/r2/controllers/post.py</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,7 @@ import r2.config as config
 from r2.models import *
 from errors import ErrorSet
 from validator import *
-from r2.lib.template_helpers import reddit_link
+from r2.lib.template_helpers import add_sr
 from r2.lib.jsontemplates import api_type
 
 from copy import copy
@@ -105,7 +105,7 @@ def set_user_cookie(name, val):
     uname = c.user.name if c.user_is_loggedin else &quot;&quot;
     c.response.set_cookie(uname + '_' + name,
                           value = val,
-                          domain = c.domain)
+                          domain = g.domain)
 
 def read_click_cookie():
     if c.user_is_loggedin:
@@ -129,7 +129,7 @@ def firsttime():
         if not request.cookies.get(&quot;reddit_first&quot;):
             c.response.set_cookie(&quot;reddit_first&quot;, &quot;first&quot;,
                                   expires = NEVER,
-                                  domain = c.domain)
+                                  domain = g.domain)
             return True
     return False
 
@@ -146,7 +146,9 @@ def set_subreddit():
     sr_name=request.environ.get(&quot;subreddit&quot;, request.params.get('r'))
 
     if not sr_name or sr_name == Default.name:
-        c.site = Default
+        sub_domain = request.environ.get('sub_domain')
+        sr = Subreddit._by_domain(sub_domain) if sub_domain else None
+        c.site = sr or Default
     elif sr_name == 'r':
         c.site = Sub
     else:
@@ -191,6 +193,12 @@ def set_content_type():
         c.response_wrappers.append(utils.to_js)
     elif extension == 'mobile':
         c.render_style = 'mobile'
+    #Insert new extentions above this line
+    elif extension not in ('', 'html'):
+        dest = &quot;http://%s%s&quot; % (request.host, request.path)
+        if request.get:
+            dest += utils.query_string(request.get)
+        redirect_to(dest)
 
 def get_browser_langs():
     browser_langs = []
@@ -252,6 +260,11 @@ def set_content_lang():
     else:
         c.content_langs = c.user.pref_content_langs
 
+def set_cnameframe():
+    if (bool(request.params.get('cnameframe')) 
+        or request.host.split(&quot;:&quot;)[0] != g.domain):
+        c.cname = True
+
 def ratelimit_agents():
     user_agent = request.user_agent
     for s in g.agents:
@@ -308,6 +321,7 @@ class RedditController(BaseController):
         key = ''.join((str(c.lang),
                        str(c.content_langs),
                        request.host,
+                       c.cname, 
                        request.fullpath,
                        str(c.firsttime),
                        str(c.over18)))
@@ -367,14 +381,15 @@ class RedditController(BaseController):
         set_content_type()
         set_iface_lang()
         set_content_lang()
+        set_cnameframe()
 
         # check if the user has access to this subreddit
         if not c.site.can_view(c.user):
             abort(403, &quot;forbidden&quot;)
  
         #check over 18
-        if c.site.over_18 and not c.over18:
-            d = dict(dest=reddit_link(request.path, url = True) + utils.query_string(request.GET))
+        if c.site.over_18 and not c.over18 and not request.path == &quot;/frame&quot;:
+            d = dict(dest=add_sr(request.path) + utils.query_string(request.GET))
             return redirect_to(&quot;/over18&quot; + utils.query_string(d))
 
         #check content cache
@@ -425,7 +440,7 @@ class RedditController(BaseController):
     def check_modified(self, thing, action):
         if c.user_is_loggedin:
             return
-
+        
         date = utils.is_modified_since(thing, action, request.if_modified_since)
         if date is True:
             abort(304, 'not modified')</diff>
      <filename>r2/r2/controllers/reddit_base.py</filename>
    </modified>
    <modified>
      <diff>@@ -21,6 +21,7 @@
 ################################################################################
 from pylons.controllers.util import redirect_to
 from r2.lib.base import BaseController
+from pylons import c
 
 class RedirectController(BaseController):
     def GET_redirect(self, dest):</diff>
      <filename>r2/r2/controllers/redirect.py</filename>
    </modified>
    <modified>
      <diff>@@ -26,7 +26,7 @@ from r2.lib import utils, captcha
 from r2.lib.filters import unkeep_space, websafe
 from r2.lib.db.operators import asc, desc
 from r2.config import cache
-from r2.lib.template_helpers import reddit_link
+from r2.lib.template_helpers import add_sr
 from r2.lib.jsonresponse import json_respond
 
 from r2.models import *
@@ -77,8 +77,10 @@ def validate(*simple_vals, **param_vals):
                 return fn(self, *a, **kw)
 
             except UserRequiredException:
-                d = dict(dest=reddit_link(request.path, url = True)
-                         + utils.query_string(request.GET))
+                d = dict(dest=add_sr(request.path) + 
+                         utils.query_string(request.GET))
+                if c.cname:
+                    d['cnameframe'] = 1
                 path = &quot;/login&quot;
                 if request.environ.get('extension'):
                     path += &quot;.%s&quot; % request.environ['extension']
@@ -633,19 +635,22 @@ class VReason(Validator):
 
         if reason.startswith('redirect_'):
             dest = reason[9:]
+            if (not dest.startswith(c.site.path) and 
+                not dest.startswith(&quot;http:&quot;)):
+                dest = (c.site.path + dest).replace('//', '/')
             return ('redirect', dest)
         if reason.startswith('vote_'):
             fullname = reason[5:]
             t = Thing._by_fullname(fullname, data=True)
-            return ('redirect', t.permalink)
+            return ('redirect', t.make_permalink_slow())
         elif reason.startswith('share_'):
             fullname = reason[6:]
             t = Thing._by_fullname(fullname, data=True)
-            return ('redirect', t.permalink)
+            return ('redirect', t.make_permalink_slow())
         elif reason.startswith('reply_'):
             fullname = reason[6:]
             t = Thing._by_fullname(fullname, data=True)
-            return ('redirect', t.permalink)
+            return ('redirect', t.make_permalink_slow())
         elif reason.startswith('sr_change_'):
             sr_list = reason[10:].split(',')
             fullnames = dict(i.split(':') for i in sr_list)
@@ -695,6 +700,17 @@ class ValidEmails(Validator):
             # return single email if one is expected, list otherwise
             return list(emails)[0] if self.num == 1 else emails
 
+
+class VCnameDomain(Validator):
+    domain_re  = re.compile(r'.+\..+')
+
+    def run(self, domain):
+        if (domain
+            and (not self.domain_re.match(domain)
+                 or domain.endswith('.reddit.com'))):
+            c.errors.add(errors.BAD_CNAME)
+        return domain or ''
+
 # NOTE: make sure *never* to have res check these are present
 # otherwise, the response could contain reference to these errors...!
 class ValidIP(Validator):</diff>
      <filename>r2/r2/controllers/validator/validator.py</filename>
    </modified>
    <modified>
      <diff>@@ -49,7 +49,8 @@ class Globals(object):
                   'uncompressedJS',
                   'enable_doquery',
                   'use_query_cache',
-                  'write_query_queue']
+                  'write_query_queue',
+                  'css_killswitch']
 
     tuple_props = ['memcaches',
                    'rec_cache',
@@ -57,6 +58,7 @@ class Globals(object):
                    'monitored_servers',
                    'default_srs',
                    'agents',
+                   'allowed_css_linked_domains',
                    'query_caches']
 
     def __init__(self, global_conf, app_conf, paths, **extra):
@@ -157,7 +159,15 @@ class Globals(object):
         self.log.addHandler(logging.StreamHandler())
         if self.debug:
             self.log.setLevel(logging.DEBUG)
-            
+
+        #read in our CSS so that it can become a default for subreddit
+        #stylesheets
+        stylesheet_path = os.path.join(paths.get('static_files'),
+                                       self.static_path.lstrip('/'),
+                                       self.stylesheet)
+        with open(stylesheet_path) as s:
+            self.default_stylesheet = s.read()
+
     def __del__(self):
         &quot;&quot;&quot;
         Put any cleanup code to be run when the application finally exits </diff>
      <filename>r2/r2/lib/app_globals.py</filename>
    </modified>
    <modified>
      <diff>@@ -94,8 +94,12 @@ class BaseController(WSGIController):
 
     @staticmethod
     def redirect(dest, code = 302):
-        c.response.headers['Location'] = _force_unicode(dest).encode('utf8')
+        dest = _force_unicode(dest).encode('utf8')
+        if c.cname and &quot;?cnameframe=1&quot; not in red:
+            dest += &quot;?cnameframe=1&quot;
+        c.response.headers['Location'] = dest
         c.response.status_code = code
+        
         return c.response
 
     def sendjs(self,js, callback=&quot;document.write&quot;, escape=True):</diff>
      <filename>r2/r2/lib/base.py</filename>
    </modified>
    <modified>
      <diff>@@ -35,7 +35,7 @@ import logging
 log_format = logging.Formatter('sql: %(message)s')
 
 settings = storage()
-settings.DEBUG = g.debug
+settings.DEBUG = False
 settings.DB_CREATE_TABLES = True
 settings.DB_APP_NAME = 'reddit'
 </diff>
      <filename>r2/r2/lib/db/tdb_sql.py</filename>
    </modified>
    <modified>
      <diff>@@ -114,7 +114,11 @@ def safemarkdown(text):
         #wipe malicious javascript
         text = jscript_url.sub('', text)
         def href_handler(m):
-            return '&lt;a href=&quot;%s&quot;' % m.group(1).replace('&amp;amp;', '&amp;')
+            x = m.group(1).replace('&amp;amp;', '&amp;')
+            if c.cname:
+                return '&lt;a target=&quot;_top&quot; href=&quot;%s&quot;' % x
+            else:
+                return '&lt;a href=&quot;%s&quot;' % x
         def code_handler(m):
             l = m.group(1)
             return '&lt;code&gt;%s&lt;/code&gt;' % l.replace('&amp;amp;','&amp;')
@@ -125,7 +129,10 @@ def safemarkdown(text):
 
 
 def keep_space(text):
-    return unsafe(websafe(text).replace(' ', '&amp;#32;').replace('\n', '&amp;#10;').replace('\t', '&amp;#09;'))
+    text = websafe(text)
+    for i in &quot; \n\r\t&quot;:
+        text=text.replace(i,'&amp;#%02d;' % ord(i))
+    return unsafe(text)
 
 
 def unkeep_space(text):</diff>
      <filename>r2/r2/lib/filters.py</filename>
    </modified>
    <modified>
      <diff>@@ -46,7 +46,7 @@ class JsonListingStub(object):
 class JsonResponse():
     # handled entried in the response object
     __slots__ = ['update', 'blur', 'focus', 'object', 'hide', 'show',
-                 'captcha', 'success']
+                 'captcha', 'success', 'call']
 
     def __init__(self):
         self.update = []
@@ -59,6 +59,10 @@ class JsonResponse():
         self.error = None
         self.success = None
         self.redirect = None
+        self.call = []
+
+    def _call(self, fn):
+        self.call.append(fn)
 
     def _success(self):
         self.success = 1
@@ -77,7 +81,11 @@ class JsonResponse():
         self.blur = f
 
     def _redirect(self, red):
-        self.redirect = red
+        from pylons import c
+        if c.cname and &quot;?cnameframe=1&quot; not in red:
+            self.redirect = red + &quot;?cnameframe=1&quot;
+        else:
+            self.redirect = red
 
 
     def _update(self, name, **kw):</diff>
      <filename>r2/r2/lib/jsonresponse.py</filename>
    </modified>
    <modified>
      <diff>@@ -238,15 +238,17 @@ class NavButton(Styled):
     must also have its build() method called with the current path to
     set self.path.  This step is done automatically if the button is
     passed to a NavMenu instance upon its construction.&quot;&quot;&quot;
-    def __init__(self, title, dest, sr_path = True, opt = '', aliases = [],
-                 style = &quot;plain&quot;, **kw):
+    def __init__(self, title, dest, sr_path = True, 
+                 nocname=False, opt = '', aliases = [],
+                 target = &quot;&quot;, style = &quot;plain&quot;, **kw):
         
         # keep original dest to check against c.location when rendering
         self.aliases = set(a.rstrip('/') for a in aliases)
         self.aliases.add(dest.rstrip('/'))
         self.dest = dest
 
-        Styled.__init__(self, style = style, sr_path = sr_path,
+        Styled.__init__(self, style = style, sr_path = sr_path, 
+                        nocname = nocname, target = target, 
                         title = title, opt = opt, **kw)
 
     def build(self, base_path = ''):
@@ -295,10 +297,10 @@ class NamedButton(NavButton):
     'dest' defaults to the 'name' as well (unless specified
     separately).&quot;&quot;&quot;
     
-    def __init__(self, name, sr_path = True, dest = None, **kw):
+    def __init__(self, name, sr_path = True, nocname=False, dest = None, **kw):
         self.name = name.strip('/')
         NavButton.__init__(self, menu[self.name], name if dest is None else dest,
-                           sr_path = sr_path, **kw)
+                           sr_path = sr_path, nocname=nocname, **kw)
 
     def selected_title(self):
         &quot;&quot;&quot;Overrides selected_title to use menu_selected dictionary&quot;&quot;&quot;</diff>
      <filename>r2/r2/lib/menus.py</filename>
    </modified>
    <modified>
      <diff>@@ -32,7 +32,8 @@ from r2.lib.captcha import get_iden
 from r2.lib.filters import spaceCompress, _force_unicode
 from r2.lib.menus import NavButton, NamedButton, NavMenu, PageNameNav, JsButton, menu
 from r2.lib.strings import plurals, rand_strings, strings
-from r2.lib.utils import title_to_url
+from r2.lib.utils import title_to_url, query_string
+from r2.lib.template_helpers import add_sr
 import sys
 
 def get_captcha():
@@ -119,15 +120,15 @@ class Reddit(Wrapped):
 
         if self.submit_box:
             ps.append(SideBox(_('Submit a link'),
-                              c.site.path + 'submit', 'submit',
+                              '/submit', 'submit',
                               subtitles = [_('to anything interesting: news article, blog entry, video, picture...')],
                               show_cover = True))
             
         if self.create_reddit_box:
-            ps.append(SideBox(_('Create your own reddit'),
+           ps.append(SideBox(_('Create your own reddit'),
                               '/reddits/create', 'create',
                               subtitles = rand_strings.get(&quot;create_reddit&quot;, 2),
-                              show_cover = True))
+                              show_cover = True, nocname=True))
         return ps
 
     def render(self, *a, **kw):
@@ -160,9 +161,11 @@ class Reddit(Wrapped):
         if c.user_is_loggedin:
             if c.user.name in g.admins:
                 if c.user_is_admin:
-                   buttons += [NamedButton(&quot;adminoff&quot;, False)]
+                   buttons += [NamedButton(&quot;adminoff&quot;, False, nocname=True,
+                                           target = &quot;_self&quot;)]
                 else:
-                   buttons += [NamedButton(&quot;adminon&quot;,  False)]
+                   buttons += [NamedButton(&quot;adminon&quot;,  False, nocname=True,
+                                           target = &quot;_self&quot;)]
             buttons += [NamedButton(&quot;prefs&quot;, False,
                                   css_class = &quot;pref-lang&quot;)]
         else:
@@ -170,12 +173,13 @@ class Reddit(Wrapped):
             buttons += [JsButton(g.lang_name.get(lang, lang),  
                                   onclick = &quot;return showlang();&quot;,
                                   css_class = &quot;pref-lang&quot;)]
-        buttons += [NamedButton(&quot;stats&quot;, False)]
-        buttons += [NamedButton(&quot;help&quot;, False),
-                    NamedButton(&quot;blog&quot;, False)]                    
+        buttons += [NamedButton(&quot;stats&quot;, False, nocname=True)]
+        buttons += [NamedButton(&quot;help&quot;, False, nocname=True),
+                    NamedButton(&quot;blog&quot;, False, nocname=True)]                    
         
         if c.user_is_loggedin:
-            buttons += [NamedButton(&quot;logout&quot;, False)]
+            buttons += [NamedButton(&quot;logout&quot;, False, nocname=True,
+                                    target = &quot;_self&quot;)]
         
         return NavMenu(buttons, base_path = &quot;/&quot;, type = &quot;flatlist&quot;)
 
@@ -185,10 +189,10 @@ class Reddit(Wrapped):
                    NamedButton(&quot;bookmarklets&quot;, False),
                    NamedButton(&quot;buttons&quot;,      False),
                    NamedButton(&quot;widget&quot;,       False),
-                   NamedButton(&quot;code&quot;,         False),
-                   NamedButton(&quot;mobile&quot;,       False),
-                   NamedButton(&quot;store&quot;,        False),
-                   NamedButton(&quot;ad_inq&quot;,       False),
+                   NamedButton(&quot;code&quot;,         False, nocname=True),
+                   NamedButton(&quot;mobile&quot;,       False, nocname=True),
+                   NamedButton(&quot;store&quot;,        False, nocname=True),
+                   NamedButton(&quot;ad_inq&quot;,       False, nocname=True),
                    ]
 
         return NavMenu(buttons, base_path = &quot;/&quot;, type = &quot;flatlist&quot;)
@@ -217,7 +221,7 @@ class Reddit(Wrapped):
         toolbar = [NavMenu(main_buttons, type='tabmenu')]
         if more_buttons:
             toolbar.append(NavMenu(more_buttons, title=menu.more, type='tabdrop'))
-        if c.site != Default:
+        if c.site != Default and not c.cname:
             toolbar.insert(0, PageNameNav('subreddit'))
 
         return toolbar
@@ -259,10 +263,10 @@ class SubredditInfoBar(Wrapped):
 class SideBox(Wrapped):
     &quot;&quot;&quot;Generic sidebox used to generate the 'submit' and 'create a reddit' boxes.&quot;&quot;&quot;
     def __init__(self, title, link, css_class='', subtitles = [],
-                 show_cover = False):
-        Wrapped.__init__(self, link = link, 
+                 show_cover = False, nocname=False):
+        Wrapped.__init__(self, link = link, target = '_top',
                          title = title, css_class = css_class,
-                         subtitles = subtitles, show_cover = show_cover)
+                         subtitles = subtitles, show_cover = show_cover, nocname=nocname)
 
 
 class PrefsPage(Reddit):
@@ -429,7 +433,7 @@ class LinkInfoPage(Reddit):
 
         toolbar = [NavMenu(buttons, base_path = &quot;&quot;, type=&quot;tabmenu&quot;)]
 
-        if c.site != Default:
+        if c.site != Default and not c.cname:
             toolbar.insert(0, PageNameNav('subreddit'))
 
         return toolbar
@@ -463,7 +467,10 @@ class EditReddit(Reddit):
         Reddit.__init__(self, title = title, *a, **kw)
     
     def build_toolbars(self):
-        return [PageNameNav('subreddit')]
+        if not c.cname:
+            return [PageNameNav('subreddit')]
+        else:
+            return []
 
 
 
@@ -659,6 +666,24 @@ class CreateSubreddit(Wrapped):
     def __init__(self, site = None, name = ''):
         Wrapped.__init__(self, site = site, name = name)
 
+class SubredditStylesheet(Wrapped):
+    &quot;&quot;&quot;form for editing or creating subreddit stylesheets&quot;&quot;&quot;
+    def __init__(self, site = None,
+                 stylesheet_contents = ''):
+        Wrapped.__init__(self, site = site,
+                         stylesheet_contents = stylesheet_contents)
+
+class CssError(Wrapped):
+    &quot;&quot;&quot;Rendered error returned to the stylesheet editing page via ajax&quot;&quot;&quot;
+    def __init__(self, error):
+        # error is an instance of cssutils.py:ValidationError
+        Wrapped.__init__(self, error = error)
+
+class UploadedImage(Wrapped):
+    &quot;The page rendered in the iframe during an upload of a header image&quot;
+    def __init__(self,status,img_src,op):
+        Wrapped.__init__(self,
+                         status=status, img_src=img_src, op=op)
 
 class Password(Wrapped):
     &quot;&quot;&quot;Form encountered when 'recover password' is clicked in the LoginFormWide.&quot;&quot;&quot;
@@ -1042,3 +1067,15 @@ class DetailsPage(LinkInfoPage):
         from admin_pages import Details
         return self.content_stack(self.link_listing, Details(link = self.link))
         
+class Cnameframe(Wrapped):
+    &quot;&quot;&quot;The frame page.&quot;&quot;&quot;
+    def __init__(self, original_path, sr_name, sr_title, sub_domain):
+        Wrapped.__init__(self, original_path=original_path)
+        self.title = &quot;%s - %s&quot; % (sr_title, sub_domain)
+        port = request.environ.get('request_port')
+        request.get['cnameframe'] = 1
+        path = original_path + query_string(request.get)
+        if port &gt; 0:
+            self.frame_target = &quot;http://%s:%d/r/%s%s&quot; % (c.domain, port, sr_name, path)
+        else:
+            self.frame_target = &quot;http://%s/r/%s%s&quot; % (c.domain, sr_name, path)</diff>
      <filename>r2/r2/lib/pages/pages.py</filename>
    </modified>
    <modified>
      <diff>@@ -93,7 +93,19 @@ string_dict = dict(
 
     searching_a_reddit = _('you\'re searching within the [%(reddit_name)s](%(reddit_link)s) reddit. '+
                            'you can search within [your subscribed reddits](%(my_reddits_link)s) ' +
-                           'or [all reddits](%(all_reddits_link)s)')
+                           'or [all reddits](%(all_reddits_link)s)'),
+
+    css_validator_messages = dict(
+        broken_url = _('&quot;%(brokenurl)s&quot; is not a valid URL'),
+        invalid_property = _('&quot;%(cssprop)s&quot; is not a valid CSS property'),
+        invalid_val_for_prop = _('&quot;%(cssvalue)s&quot; is not a valid value for CSS property &quot;%(cssprop)s&quot;'),
+        too_big = _('too big. keep it under %(max_size)dkb'),
+        syntax_error = _('syntax error: &quot;%(syntaxerror)s&quot;'),
+        no_imports = _('@imports are not allowed'),
+        invalid_property_list = _('invalid CSS property list &quot;%(proplist)s&quot;'),
+        unknown_rule_type = _('unknown CSS rule type &quot;%(ruletype)s&quot;')
+    )
+    
 )
 
 class StringHandler(object):</diff>
      <filename>r2/r2/lib/strings.py</filename>
    </modified>
    <modified>
      <diff>@@ -53,7 +53,6 @@ def static(file):
         return file + v
     return os.path.join(c.site.static_path, file) + v
 
-
 def generateurl(context, path, **kw):
     if kw:
         return path + '?' + '&amp;'.join([&quot;%s=%s&quot;%(k, url_escape(v)) \
@@ -145,45 +144,56 @@ def replace_render(listing, item, style = None, display = True):
         rendered_item = replace_fn(u&quot;$ListClass&quot;, listing._js_cls)
 
         #$votehash is only present when voting arrows are present
-        if u'$votehash' in rendered_item:
+        if c.user_is_loggedin and u'$votehash' in rendered_item:
             hash = vote_hash(c.user, item, listing.vote_hash_type)
             rendered_item = replace_fn(u'$votehash', hash)
             
     rendered_item = replace_fn(u&quot;$display&quot;, &quot;&quot; if display else &quot;style='display:none'&quot;)
     return rendered_item
 
-from pylons import c as cur
 def dockletStr(context, type, browser):
+    domain = c.domain
+    if c.cname:
+        domain = c.site.domain
+
     if type == &quot;serendipity!&quot;:
-        return &quot;http://&quot;+cur.domain+&quot;/random&quot;
+        return &quot;http://&quot;+domain+&quot;/random&quot;
     elif type == &quot;reddit&quot;:
-        return &quot;javascript:location.href='http://&quot;+cur.domain+&quot;/submit?url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title)&quot;
+        return &quot;javascript:location.href='http://&quot;+domain+&quot;/submit?url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title)&quot;
     else:
         f = &quot;fixed&quot;
         if browser == &quot;ie&quot;: f = &quot;absolute&quot;
         return &quot;javascript:function b(){var u=encodeURIComponent(location.href);var i=document.getElementById('redstat')||document.createElement('a');var s=i.style;s.position='%s';s.top='0';s.left='0';s.zIndex='10002';i.id='redstat';i.href='http://%s/submit?url='+u+'&amp;title='+encodeURIComponent(document.title);var q=i.firstChild||document.createElement('img');q.src='http://%s/d/%s'+Math.random()+'?uh=%s&amp;u='+u;i.appendChild(q);document.body.appendChild(i)};b()&quot; % \
-            (f, cur.domain, cur.domain, type, 
-             c.modhash if cur.user else '')
+            (f, domain, domain, type, 
+             c.modhash if c.user else '')
+
+
+
+def add_sr(path, sr_path = True, nocname=False):
+    &quot;&quot;&quot;Given a link, returns that link with the subreddit added.
+       Also adds the domain for cname requests.&quot;&quot;&quot;
+    (scheme, netloc, path, params, query, fragment) = urlparse(path)
+    if sr_path:
+        #noslash fixes /reddits/
+        noslash = c.site.path.rstrip('/')
+        #if it's a relative path, don't include the sitename
+        if (path.startswith('/') and not path.startswith(noslash)
+            and not path.startswith('/r/')):
+            if not c.cname:
+                path = c.site.path + path[1:]
 
+    if not netloc and c.cname and not nocname:
+        netloc = getattr(c.site, 'domain', None)
 
+    if netloc:
+        port = request.environ.get('request_port')
+        if port &gt; 0:
+            netloc = &quot;%s:%d&quot; % (netloc, port)
+            
+    if c.render_style == 'mobile' and not path.endswith('.mobile'):
+        path += '.mobile'
 
-def reddit_link(path, url = False, get = False):
-    if url or get:
-        (scheme, netloc, path, params, query, fragment) = urlparse(path)
-        if url:
-            #noslash fixes /reddits/
-            noslash = c.site.path.rstrip('/')
-            #if it's a relative path, don't include the sitename
-            if path.startswith('/') and not path.startswith(noslash):
-                path = c.site.path + path[1:]
-        else:
-            newparam = &quot;r=&quot; + url_escape(c.site.name)
-            if query:
-                query += &quot;&amp;&quot; + newparam
-            else:
-                query = newparam
-        return urlunparse((scheme, netloc, path, params, query, fragment))
-    return path
+    return urlunparse((scheme, netloc, path, params, query, fragment))
 
 def join_urls(*urls):
     &quot;&quot;&quot;joins a series of urls together without doubles slashes&quot;&quot;&quot;</diff>
      <filename>r2/r2/lib/template_helpers.py</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ def is_modified_since(thing, action, date):
     which means a 304 should be returned. Otherwise returns the date
     that should be sent as the last-modified header.&quot;&quot;&quot;
     from pylons import g
-    
+
     prop = 'last_' + action
     if not hasattr(thing, prop):
         last_modified = make_last_modified()</diff>
      <filename>r2/r2/lib/utils/thing_utils.py</filename>
    </modified>
    <modified>
      <diff>@@ -51,6 +51,7 @@ class Account(Thing):
                      pref_over_18 = False,
                      pref_compress = False,
                      pref_organic = True,
+                     pref_show_stylesheets = True,
                      reported = 0,
                      report_made = 0,
                      report_correct = 0,</diff>
      <filename>r2/r2/models/account.py</filename>
    </modified>
    <modified>
      <diff>@@ -79,7 +79,7 @@ class Link(Thing, Printable):
 
     @property
     def already_submitted_link(self):
-        return self.permalink + '?already_submitted=true'
+        return self.make_permalink_slow() + '?already_submitted=true'
 
     def resubmit_link(self, sr_url = False):
         submit_url  = self.subreddit_slow.path if sr_url else '/'
@@ -193,7 +193,9 @@ class Link(Thing, Printable):
                               c.user.pref_newwindow,
                               c.user.pref_frame,
                               c.user.pref_compress,
+                              c.user.pref_media,
                               request.host,
+                              c.cname, 
                               wrapped.author == c.user,
                               wrapped.likes,
                               wrapped.saved,
@@ -208,10 +210,19 @@ class Link(Thing, Printable):
         s = ''.join(s)
         return s
 
-    @property
-    def permalink(self):
-        return &quot;/comments/%s/%s/&quot; % (self._id36, title_to_url(self.title))
+    def make_permalink(self, sr):
+        p = &quot;comments/%s/%s/&quot; % (self._id36, title_to_url(self.title))
+        if not c.cname:
+            res = &quot;/r/%s/%s&quot; % (sr.name, p)
+        elif sr != c.site:
+            res = &quot;http://%s/r/%s/%s&quot; % (g.domain, sr.name, p)
+        else:
+            res = &quot;/%s&quot; % p
+        return res
 
+    def make_permalink_slow(self):
+        return self.make_permalink(self.subreddit_slow)
+    
     @classmethod
     def add_props(cls, user, wrapped):
         from r2.lib.count import incr_counts
@@ -247,6 +258,7 @@ class Link(Thing, Printable):
             item.clicked = bool(clicked.get((user, item, 'click')))
             item.num = None
             item.score_fmt = Score.number_only
+            item.permalink = item.make_permalink(item.subreddit)
                 
         if c.user_is_loggedin:
             incr_counts(wrapped)
@@ -333,6 +345,7 @@ class Comment(Thing, Printable):
                               bool(c.user_is_loggedin),
                               c.focal_comment == self._id36,
                               request.host,
+                              c.cname, 
                               wrapped.author == c.user,
                               wrapped.likes,
                               wrapped.friend,
@@ -347,22 +360,18 @@ class Comment(Thing, Printable):
         s = ''.join(s)
         return s
 
-    @property
-    def permalink(self):
-        if not self._loaded:
-            self._load()
-
-        try:
-            l = Link._byID(self.link_id, True)
-            return l.permalink + self._id36
-        except NotFound:
-            return &quot;&quot;
-
+    def make_permalink(self, link, sr=None):
+        return link.make_permalink(sr) + self._id36
 
+    def make_permalink_slow(self):
+        l = Link._byID(self.link_id, data=True)
+        return self.make_permalink(l, l.subreddit_slow)
+    
     @classmethod
     def add_props(cls, user, wrapped):
         #fetch parent links
         links = Link._byID(set(l.link_id for l in wrapped), True)
+        
 
         #get srs for comments that don't have them (old comments)
         for cm in wrapped:
@@ -378,19 +387,20 @@ class Comment(Thing, Printable):
         cids = dict((w._id, w) for w in wrapped)
 
         for item in wrapped:
+            item.link = links.get(item.link_id)
+            if not hasattr(item, 'subreddit'):
+                item.subreddit = item.subreddit_slow
             if hasattr(item, 'parent_id'):
                 if cids.has_key(item.parent_id):
                     item.parent_permalink = '#' + utils.to36(item.parent_id)
                 else:
                     parent = Comment._byID(item.parent_id)
-                    item.parent_permalink = parent.permalink
+                    item.parent_permalink = parent.make_permalink(item.link, item.subreddit)
             else:
                 item.parent_permalink = None
 
             item.can_reply = (item.sr_id in can_reply_srs)
 
-            if not hasattr(item, 'subreddit'):
-                item.subreddit = item.subreddit_slow
 
             # not deleted on profile pages,
             # deleted if spam and not author or admin
@@ -406,12 +416,12 @@ class Comment(Thing, Printable):
                                   item.deleted or
                                   c.user_is_admin))
                 
-            item.link = links.get(item.link_id)
             if not hasattr(item,'editted'):
                 item.editted = False
             #will get updated in builder
             item.num_children = 0
             item.score_fmt = Score.points
+            item.permalink = item.make_permalink(item.link, item.subreddit)
 
 class MoreComments(object):
     show_spam = False
@@ -432,7 +442,7 @@ class MoreComments(object):
         if parent:
             self.parent_id = parent._id
             self.parent_name = parent._fullname
-            self.parent_permalink = parent.permalink
+            self.parent_permalink = parent.make_permalink(link)
         self.link_name = link._fullname
         self.link_id = link._id
         self.depth = depth</diff>
      <filename>r2/r2/models/link.py</filename>
    </modified>
    <modified>
      <diff>@@ -21,10 +21,10 @@
 ################################################################################
 from r2.models import *
 
-def populate():
-    sr = Subreddit._new(name= 'reddit.com', title = &quot;reddit.com: what's new online&quot;)
+def populate(sr_name = 'reddit.com', start_account = 1, sr_title = &quot;reddit.com: what's new online&quot;):
+    sr = Subreddit._new(name= sr_name, title = sr_title)
     sr._commit()
-    for i in range(1,5):
+    for i in range(start_account,(start_account + 4)):
         name = 'test' + str(i)
         password = name
         user = register(name, password)</diff>
      <filename>r2/r2/models/populatedb.py</filename>
    </modified>
    <modified>
      <diff>@@ -30,6 +30,7 @@ from r2.lib.db.operators import lower, or_, and_, desc
 from r2.lib.memoize import memoize, clear_memo
 from r2.lib.utils import tup
 from r2.lib.strings import strings, Score
+from r2.lib.filters import _force_unicode
 
 import os.path
 
@@ -37,6 +38,8 @@ class Subreddit(Thing, Printable):
     _defaults = dict(static_path = g.static_path,
                      stylesheet = None,
                      stylesheet_rtl = None,
+                     stylesheet_contents = '',
+                     stylesheet_hash     = '0',
                      description = None,
                      firsttext = strings.firsttext,
                      header = os.path.join(g.static_path,
@@ -45,6 +48,7 @@ class Subreddit(Thing, Printable):
                      reported = 0,
                      valid_votes = 0,
                      show_media = False,
+                     domain = None,
                      )
 
     @classmethod
@@ -91,6 +95,24 @@ class Subreddit(Thing, Printable):
             else:
                 raise NotFound, 'Subreddit %s' % name
 
+    @classmethod
+    @memoize('subreddit._by_domain')
+    def _by_domain_cache(cls, name):
+        q = cls._query(cls.c.domain == name,
+                       cls.c.over_18 == (True, False),
+                       limit = 1)
+        l = list(q)
+        if l:
+            return l[0]._id
+
+    @classmethod
+    def _by_domain(cls, domain):
+        sr_id = cls._by_domain_cache(_force_unicode(domain))
+        if sr_id:
+            return cls._byID(sr_id, True)
+        else:
+            return None
+
     @property
     def moderators(self):
         return self.moderator_ids()
@@ -138,6 +160,12 @@ class Subreddit(Thing, Printable):
                 and (c.user_is_admin
                      or self.is_moderator(user)))
 
+    def can_change_stylesheet(self, user):
+        if c.user_is_loggedin:
+            return c.user_is_admin or self.is_moderator(user)
+        else:
+            return False
+
     def is_special(self, user):
         return (user
                 and (c.user_is_admin
@@ -341,6 +369,9 @@ class FakeSubreddit(Subreddit):
     def can_submit(self, user):
         return False
 
+    def can_change_stylesheet(self, user):
+        return False
+
     def is_banned(self, user):
         return False
 </diff>
      <filename>r2/r2/models/subreddit.py</filename>
    </modified>
    <modified>
      <diff>@@ -39,7 +39,7 @@ document.write('&lt;script language=&quot;JavaScript&quot; src=&quot;http://ad.doubleclick.net/adj
 &lt;/div&gt;
 
 &lt;div id=&quot;adlink&quot;&gt;
-&lt;a target=&quot;_parent&quot; href=&quot;#&quot; onclick=&quot;rwt(this)&quot;&gt;reddit this ad&lt;/a&gt;
+&lt;a target=&quot;_top&quot; href=&quot;#&quot; onclick=&quot;rwt(this)&quot;&gt;reddit this ad&lt;/a&gt;
 &lt;/div&gt;
 
 &lt;/body&gt;</diff>
      <filename>r2/r2/public/static/ad_default.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,17 @@
-body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td,iframe{ margin:0;padding:0;}
-table{ border-collapse:collapse;}
-fieldset,img{ border:0;}
-address,caption,cite,code,dfn,em,strong,th,var{ font-style:normal;font-weight:normal;}
-ol,ul { list-style:none;}
-caption,th { text-align:left;}
-h1,h2,h3,h4,h5,h6{ font-size:100%;}
-q:before,q:after{ content:'';}
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td,iframe {
+  margin:0;
+  padding:0;
+}
+
+table { border-collapse:collapse; }
+
+fieldset,img { border:0; }
+
+address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; }
+ol,ul { list-style:none; }
+caption,th { text-align:left; }
+h1,h2,h3,h4,h5,h6 { font-size:100%; }
+q:before,q:after { content:''; }
 
 body {
     font: normal x-small verdana, arial, helvetica, sans-serif;
@@ -13,8 +19,12 @@ body {
     z-index: 1;
 }
 
-html,body { height: 100% }
+html,body { height: 100%; }
 
+/* IE dumbness patch. hidden input in a hidden block that is
+subsequently shown leads to the input to &quot;show&quot; and generate undesired
+padding.  This makes it go away. */ 
+input[type=hidden] { position: absolute; }
 
 /* html element defaults */
 
@@ -85,10 +95,7 @@ input.txt {
     background-color: #cee3f8;
 }
 
-#header-img {
-    height: 40px;
-    width: 120px;
-}
+#header-img {}
 
 #header-top {
     position: absolute;
@@ -460,25 +467,14 @@ before enabling */
     height: 14px;
     display: block;
     cursor: pointer;
-    background-position: center 0px;
+    background-position: center center;
+    background-repeat: no-repeat; 
 }
 
-.arrow.upmod { 
-    background: url(/static/aupmod.png); 
-    background-repeat: no-repeat;
-    background-position: center 0px; }
-.arrow.downmod { 
-    background: url(/static/adownmod.png); 
-    background-repeat: no-repeat;
-    background-position: center 0px; }
-.arrow.up { 
-    background: url(/static/aupgray.png); 
-    background-repeat: no-repeat; 
-    background-position: center 0px; }
-.arrow.down { 
-    background: url(/static/adowngray.png); 
-    background-repeat: no-repeat; 
-    background-position: center 0px;}
+.arrow.upmod { background-image: url(/static/aupmod.png); }
+.arrow.downmod { background-image: url(/static/adownmod.png); }
+.arrow.up { background-image: url(/static/aupgray.png); }
+.arrow.down { background-image: url(/static/adowngray.png); }
 
 .midcol { 
     float: left; 
@@ -1196,7 +1192,12 @@ a.star { text-decoration: none; color: #ff8b60 }
 
 #preview { float: right; width: 20em; margin-right: 10px; }
 #preview span { color: lightgray;  }
-#preview #previewbox { border: .2em dashed lightgray; padding: 1em; }
+#preview #previewbox {
+  border-width: .2em;
+  border-style: dashed;
+  border-color: lightgray;
+  padding: 1em;
+}
 
 .pretty-form { 
     font-size: larger;
@@ -1204,6 +1205,7 @@ a.star { text-decoration: none; color: #ff8b60 }
  }
 
 .pretty-form input[type=checkbox] {margin: 3px .5em;}
+.pretty-form p {margin: 3px .5em;}
 .pretty-form input[type=radio] {margin: 3px .5em 0px .5em; vertical-align:top}
 .pretty-form img { margin: 3px .5em}
 .pretty-form input[type=text],
@@ -1280,3 +1282,63 @@ a.star { text-decoration: none; color: #ff8b60 }
     overflow: hidden;
 }
 
+
+/* CSS customisation page */
+
+.stylesheet-customize-container { }
+.stylesheet-customize-container textarea { margin: 0; padding: 0px; }
+
+.sheets { margin-right: 315px; }
+.sheets .col { float: left;  }
+.sheets .col &gt; div { margin: 0 5px; }
+.sheets .col textarea { width: 100% }
+.sheets .buttons { margin-left: 5px }
+.sheets .btn { margin-left: 0px; margin-right: 5px; }
+.sheets .btn.right { float: right; margin-right: 3px;}
+
+.stylesheet-customize-container h2 { margin-top: 15px; margin-bottom: 10px;  }
+
+#validation-errors { 
+    margin-left: 40px; 
+    margin-top: 10px; 
+    list-style-type: disc;
+}
+
+#validation-errors a,
+#validation-errors li,
+.errors h2 { color: red }
+
+#validation-errors a:hover { text-decoration: underline; }
+#validation-errors pre { padding: 10px; color: black; }
+
+#preview-table { 
+    padding-right: 15px;  
+}
+#preview-table &gt; table {  
+    border-width: .2em;
+    border-style: dashed;
+    border-color: lightgray;
+    padding: 5px; 
+    margin: 5px; 
+    width: 100%;
+}
+
+#preview-table &gt; table &gt; tbody &gt; tr { padding-bottom: 10px;  }
+#preview-table &gt; table &gt; tbody &gt; tr &gt; td { padding: 5px; padding-right: 15px;}
+#preview-table &gt; table &gt; tbody &gt; tr &gt; th { padding: 5px; padding-right: 15px;}
+#preview-table &gt; table &gt; tbody &gt; tr &gt; th { 
+    font-weight: bold; 
+    vertical-align: top;
+    font-size: larger;
+    text-align: right;
+}
+
+#header-img-preview-container {
+    border-width: .2em;
+    border-style: dashed;
+    border-color: lightgray;
+    padding: 5px; 
+    margin: 5px; 
+    float: left;
+}    
+</diff>
      <filename>r2/r2/public/static/reddit.css</filename>
    </modified>
    <modified>
      <diff>@@ -112,6 +112,9 @@ function redditRequest(op, parameters, worker_in, block) {
     if (post_site) {
         parameters.r = post_site;
     }
+    if (cnameframe) {
+        parameters.cnameframe = 1;
+    }
     op = api_loc + op;
     if(!worker) {
         worker = handleResponse(action);
@@ -161,6 +164,183 @@ function tup(x) {
     return x;
 }
 
+function stylesheetSave(form, formID) {
+  form.op.value = &quot;save&quot;;
+  return post_form(form, formID);
+}
+
+function stylesheetPreview(formID, textboxID) {
+  var form = document.getElementById(formID);
+  form.op.value = &quot;preview&quot;;
+  post_form(form, formID);
+
+  applyStylesheetFromTextbox(textboxID);
+}
+
+function applyStylesheetFromTextbox(textboxID) {
+  var textbox = document.getElementById(textboxID);
+  var cssText = textbox.value;
+  return applyStylesheet(cssText);
+}
+
+function applyStylesheet(cssText) {
+  /* also referred to in the reddit.html template, for the name of the
+     stylesheet set for this reddit. These must be in sync, because
+     I'm over-writing it here */
+  var sheet_title = 'applied_subreddit_stylesheet';
+
+  if(document.styleSheets[0].cssText) {
+    /* of course IE has to do this differently from everyone else. */
+    for(var x=0; x &lt; document.styleSheets.length; x++) {
+      if(document.styleSheets[x].title == sheet_title) {
+        document.styleSheets[x].cssText = cssText;
+        break;
+      }
+    }
+  } else {
+    /* for everyone else, we walk &lt;head&gt; for the &lt;link&gt; or &lt;style&gt;
+       that has the old stylesheet, and delete it. Then we add a
+       &lt;style&gt; with the new one */
+    var headNode  = document.getElementsByTagName(&quot;head&quot;)[0];
+    var headNodes = headNode.childNodes;
+
+    for(var x=0; x &lt; headNodes.length; x++) {
+      var node = headNodes[x];
+    
+      if(node.title == sheet_title) {
+        headNode.removeChild(node);
+        break;
+      }
+    }
+
+    var appliedCSSNode = document.createElement('style');
+    appliedCSSNode.type = 'text/css';
+    appliedCSSNode.rel = 'stylesheet';
+    appliedCSSNode.media = 'screen';
+    appliedCSSNode.title = sheet_title;
+    
+    appliedCSSNode.textContent = cssText;
+    
+    headNode.appendChild(appliedCSSNode);
+  }
+}
+
+function showDefaultStylesheet() {
+  return toggleDefaultStylesheet(true);
+}
+function hideDefaultStylesheet() {
+  return toggleDefaultStylesheet(false);
+}
+function toggleDefaultStylesheet(p_show) {
+  var stylesheet_contents = $('stylesheet_contents').parentNode.parentNode;
+  var default_stylesheet  = $('default_stylesheet').parentNode.parentNode;
+  
+  var show_button  = $('show_default_stylesheet');
+  var hide_button  = $('hide_default_stylesheet');
+
+  if(p_show) {
+      default_stylesheet.style.width = &quot;50%&quot;;
+      stylesheet_contents.style.width = &quot;50%&quot;;
+      show(default_stylesheet, hide_button);
+      hide(show_button);
+  } else {
+      stylesheet_contents.style.width = &quot;100%&quot;;
+      default_stylesheet.style.width = &quot;&quot;;
+      show(show_button);
+      hide(default_stylesheet, hide_button);
+  }
+
+  return false; // don't post the form
+}
+
+function gotoTextboxLine(textboxID, lineNo) {
+  var textbox = $(textboxID);
+  var text = textbox.value;
+
+  var newline = '\n';
+  var newline_length = 1;
+  var caret_pos = 0;
+
+  if ( text.indexOf('\r') &gt; 0) {
+    /* IE hack */
+    newline = '\r';
+    newline_length = 0;
+    caret_pos = 1;
+  }
+
+  var lines = textbox.value.split(newline);
+
+  for(var x=0; x&lt;lineNo-1; x++) {
+    caret_pos += lines[x].length + newline_length;
+  }
+  var end_pos = caret_pos;
+  if (lineNo &lt; lines.length) {
+      end_pos += lines[lineNo-1].length + newline_length;
+  }
+ 
+
+  textbox.focus();
+  if(textbox.createTextRange) {   /* IE */
+      var start = textbox.createTextRange();
+      start.move('character', caret_pos);
+      var end = textbox.createTextRange();
+      end.move('character', end_pos);
+      start.setEndPoint(&quot;StartToEnd&quot;, end);
+      start.select();
+  } else if (textbox.selectionStart) {
+      textbox.setSelectionRange(caret_pos, end_pos);
+  }
+
+  if(textbox.scrollHeight) {
+      var avgLineHight = textbox.scrollHeight / lines.length;
+      textbox.scrollTop = (lineNo-2) * avgLineHight;
+  }
+}
+
+function uploadHeaderImage(status) {
+  var form = $('upload-header-image');
+  var iframe = $('upload-header-iframe');
+
+  form.op.value = 'upload';
+  $('img-status').innerHTML = status;
+  show('img-status');
+
+  form.submit();
+
+  return false;
+}
+
+function deleteHeaderImage(status) {
+  var form = $('upload-header-image');
+  var iframe = $('upload-header-iframe');
+
+  form.reset();
+  form.op.value = 'delete';
+  $('img-status').innerHTML = status;
+  show('img-status');
+
+  form.submit();
+
+  return false;
+}
+
+function completedUploadHeaderImage(status,img_src,op) {
+  show('img-status');
+  $('img-status').innerHTML = status;
+  $('upload-header-image').reset();
+
+  $('header-img').src = img_src;
+
+  if(op == 'delete') {
+    hide('delete-header-img');
+    hide('header-img-preview-container');
+  } else {
+    $('header-img-preview').src = img_src;
+    show('delete-header-img');
+    show('header-img-preview-container');
+  }
+}
+
 function handleResponse(action) {
     var my_iter = function(x, func) {
         if(x) {
@@ -209,6 +389,13 @@ function handleResponse(action) {
                         }
                     });
         }
+        // handle applied CSS
+        if(r.call) {
+          var calls = r.call;
+          for(var i=0; i&lt;calls.length; i++) {
+            eval(calls[i]);
+          }
+        }
         // handle shifts of focus
         if (r.focus) {
             var f = $(r.focus);
@@ -387,4 +574,4 @@ function view_embeded_media(id, media_link) {
 	closespan.style.display = &quot;none&quot;;
     }
 
-}
\ No newline at end of file
+}</diff>
      <filename>r2/r2/public/static/utils.js</filename>
    </modified>
    <modified>
      <diff>@@ -46,7 +46,10 @@ ${self.robots()}
 
   var logged = ${c.user_is_loggedin and (&quot;'%s'&quot; % c.user.name) or &quot;false&quot;};
   var post_site = &quot;${c.site.name}&quot;;
+  var cnameframe  = ${'true' if c.cname else 'false'}; 
   var modhash = ${&quot;'%s'&quot; % c.modhash or &quot;false&quot;};
+  
+
 &lt;/script&gt; 
 
 ${self.javascript()}</diff>
      <filename>r2/r2/templates/base.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-## &quot;The contents of this file are subject to the Common Public Attribution
+## The contents of this file are subject to the Common Public Attribution
 ## License Version 1.0. (the &quot;License&quot;); you may not use this file except in
 ## compliance with the License. You may obtain a copy of the License at
 ## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public</diff>
      <filename>r2/r2/templates/bookmarklets.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-## &quot;The contents of this file are subject to the Common Public Attribution
+## The contents of this file are subject to the Common Public Attribution
 ## License Version 1.0. (the &quot;License&quot;); you may not use this file except in
 ## compliance with the License. You may obtain a copy of the License at
 ## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
@@ -17,13 +17,13 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.&quot;
+## CondeNet, Inc. All Rights Reserved.
 ################################################################################
 
 &lt;%!
    from r2.lib.filters import keep_space
 %&gt;
-&lt;%namespace file=&quot;utils.html&quot; import=&quot;error_field, language_tool&quot;/&gt;
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;error_field, language_tool, plain_link&quot;/&gt;
 
 &lt;script type=&quot;text/javascript&quot;&gt;
 function update_title() {
@@ -113,6 +113,7 @@ function update_title() {
           %endif
         &lt;/td&gt;
       &lt;/tr&gt;
+
       &lt;tr&gt;
         &lt;th&gt;
           &lt;label for=&quot;description&quot;&gt;${_(&quot;description&quot;)}&lt;/label&gt;
@@ -129,6 +130,7 @@ function update_title() {
           ${error_field(&quot;DESC_TOO_LONG&quot;, &quot;span&quot;)}
         &lt;/td&gt;
       &lt;/tr&gt;
+
       %if c.user_is_admin:
       &lt;tr&gt;
         &lt;th&gt;
@@ -248,15 +250,36 @@ function update_title() {
           &lt;/label&gt;
         &lt;/td&gt;
       &lt;/tr&gt;
-  
+      &lt;tr&gt;
+        &lt;th&gt;
+          &lt;label for=&quot;domain&quot;&gt;${_(&quot;domain&quot;)}&lt;/label&gt;
+        &lt;/th&gt;
+        &lt;td&gt;
+          %if thing.site:
+            &lt;input id=&quot;domain&quot; type=&quot;text&quot; name=&quot;domain&quot; class=&quot;text&quot;
+                   value=&quot;${getattr(thing.site, 'domain', None) or &quot;&quot;}&quot;/&gt;
+          %else:
+            &lt;input id=&quot;domain&quot; type=&quot;text&quot; name=&quot;domain&quot; class=&quot;text&quot; /&gt;
+          %endif
+        &lt;/td&gt;
+        &lt;td id=&quot;note_domain&quot;&gt;
+          ${error_field(&quot;BAD_CNAME&quot;, &quot;span&quot;)}
+          ${error_field(&quot;USED_CNAME&quot;, &quot;span&quot;)}
+          %if not thing.site:
+            &lt;span class=&quot;gray&quot; id=&quot;example_domain&quot;&gt;
+              ${_(&quot;e.g. reddit.slashdot.org (optional)&quot;)}
+            &lt;/span&gt;
+          %endif
+        &lt;/td&gt;
+      &lt;/tr&gt;
       &lt;tr&gt;
         &lt;th&gt;
         &lt;/th&gt;
         &lt;td colspan=&quot;2&quot;&gt;
           %if thing.site:
-          &lt;button name=&quot;edit&quot; type=&quot;submit&quot;&gt;${_(&quot;update&quot;)}&lt;/button&gt;
+          &lt;button name=&quot;edit&quot; class=&quot;btn&quot; type=&quot;submit&quot;&gt;${_(&quot;update&quot;)}&lt;/button&gt;
           %else:
-          &lt;button name=&quot;create&quot; type=&quot;submit&quot;&gt;${_(&quot;create&quot;)}&lt;/button&gt;
+          &lt;button name=&quot;create&quot; class=&quot;btn&quot; type=&quot;submit&quot;&gt;${_(&quot;create&quot;)}&lt;/button&gt;
           %endif
           &amp;#32;
           &lt;span id=&quot;status&quot; class=&quot;error&quot;&gt;&lt;/span&gt;
@@ -266,3 +289,64 @@ function update_title() {
       &lt;/tr&gt;
     &lt;/table&gt;
   &lt;/form&gt;
+
+%if thing.site and thing.site.can_change_stylesheet(c.user) and not g.css_killswitch:
+  &lt;h1&gt;${_('change the look')}&lt;/h1&gt;
+
+  &lt;table class=&quot;content preftable pretty-form sr-form&quot;&gt;
+    &lt;tr&gt;
+      &lt;th&gt;
+        &lt;label for=&quot;stylesheet_contents&quot;&gt;${_(&quot;edit stylesheet&quot;)}&lt;/label&gt;
+      &lt;/th&gt;
+      &lt;td class=&quot;nowrap nopadding&quot;&gt;
+        &lt;p&gt;${plain_link(_('edit the stylesheet'),
+                        '/about/stylesheet',
+                        sr_path = True)}&lt;/p&gt;
+      &lt;/td&gt;
+      &lt;td id=&quot;note_stylesheet_contents&quot;&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+    
+    &lt;tr&gt;
+      &lt;th&gt;&lt;label for=&quot;file&quot;&gt;${_('upload header image')}&lt;/label&gt;&lt;/th&gt;
+      &lt;td&gt;
+        &lt;form
+         onsubmit=&quot;return uploadHeaderImage('${_('submitting')}');&quot;
+         name=&quot;upload-header-image&quot; id=&quot;upload-header-image&quot;
+         enctype=&quot;multipart/form-data&quot;
+         class=&quot;pretty-form sr-form&quot;
+         target=&quot;upload-header-iframe&quot;
+         action=&quot;/api/upload_header_img&quot; method=&quot;post&quot;&gt;
+          &lt;input type=&quot;file&quot; name=&quot;file&quot;
+           onchange=&quot;return uploadHeaderImage('${_('submitting')}')&quot; /&gt;
+          &lt;button id=&quot;delete-header-img&quot;
+           class=&quot;btn&quot;
+           onclick=&quot;return deleteHeaderImage('${_('submitting')}')&quot;
+           %if not thing.site.header:
+             style=&quot;display: none;&quot;
+           %endif
+          &gt;
+            ${_('restore default')}
+          &lt;/button&gt;
+          &lt;input type=&quot;hidden&quot; name=&quot;uh&quot; value=&quot;${c.modhash}&quot; /&gt;
+          &lt;input type=&quot;hidden&quot; name=&quot;r&quot;  value=&quot;${c.site.name}&quot; /&gt;
+          &lt;input type=&quot;hidden&quot; name=&quot;op&quot; value=&quot;upload&quot; /&gt;
+
+          &lt;span style=&quot;display: none;&quot; class=&quot;error&quot; id=&quot;img-status&quot;&gt;&lt;/span&gt;
+          &lt;iframe src=&quot;about:blank&quot;
+           width=&quot;600&quot; height=&quot;200&quot; style=&quot;display: none;&quot;
+           name=&quot;upload-header-iframe&quot; id=&quot;upload-header-iframe&quot;&gt;&lt;/iframe&gt;
+        &lt;/form&gt;
+        &lt;div id=&quot;header-img-preview-container&quot; style=&quot;display: none;&quot;&gt;
+          &lt;img id=&quot;header-img-preview&quot;
+           %if thing.site.header:
+             src=&quot;${thing.site.header}&quot;
+           %else:
+             src=&quot;/static/kill.png&quot;
+           %endif
+          / &gt;&lt;br /&gt;
+        &lt;/div&gt;
+      &lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+%endif
+</diff>
      <filename>r2/r2/templates/createsubreddit.html</filename>
    </modified>
    <modified>
      <diff>@@ -56,6 +56,9 @@
      %if c.user.pref_newwindow:
        target=&quot;_blank&quot; 
      %endif
+     %if c.cname:
+       target=&quot;_top&quot;
+     %endif
      &gt;
      ${caller.body()}
   &lt;/a&gt;
@@ -142,7 +145,7 @@
        com_label = _(&quot;comment {verb}&quot;)
      else:
        # generates &quot;XX comments&quot; as a noun
-         com_label = ungettext(&quot;comment&quot;, &quot;comments&quot;, thing.num_comments)
+       com_label = ungettext(&quot;comment&quot;, &quot;comments&quot;, thing.num_comments)
      %&gt;
   &lt;li class=&quot;first&quot;&gt;
   ${parent.comment_button(&quot;comment&quot;, fullname, com_label,</diff>
      <filename>r2/r2/templates/link.html</filename>
    </modified>
    <modified>
      <diff>@@ -25,6 +25,7 @@
     from pylons.i18n import _, ungettext
 %&gt;
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot; /&gt;
 &lt;%inherit file=&quot;printable.mobile&quot; /&gt;
 
 &lt;%def name=&quot;entry()&quot;&gt;
@@ -39,7 +40,8 @@
        com_label = _(&quot;comment&quot;) 
  %&gt;
   &lt;p class=&quot;link&quot;&gt;&lt;a href=&quot;${thing.url}&quot; class=&quot;title&quot;&gt;${thing.title}&lt;/a&gt;&lt;/p&gt;
-  &lt;p class=&quot;byline&quot;&gt;${thing.score} ${ungettext(&quot;point&quot;, &quot;points&quot;, thing.score)}&amp;nbsp;|&amp;nbsp;&lt;span class=&quot;buttons&quot;&gt;&lt;a href=&quot;${thing.permalink}&quot;&gt;${com_label}&lt;/a&gt;&lt;/span&gt;&amp;nbsp;|&amp;nbsp;${tagline()}&lt;/p&gt;
+  &lt;p class=&quot;byline&quot;&gt;${thing.score} ${ungettext(&quot;point&quot;, &quot;points&quot;, thing.score)}&amp;nbsp;|&amp;nbsp;&lt;span class=&quot;buttons&quot;&gt;
+  ${plain_link(com_label, thing.permalink)}&lt;/span&gt;&amp;nbsp;|&amp;nbsp;${tagline()}&lt;/p&gt;
 &lt;/%def&gt;
 
 &lt;%def name=&quot;domain()&quot; buffered=&quot;True&quot;&gt;</diff>
      <filename>r2/r2/templates/link.mobile</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,7 @@
 
 &lt;%!
    from pylons.i18n import _, ungettext
-   from r2.lib.template_helpers import reddit_link
+   from r2.lib.template_helpers import add_sr
 %&gt;
 
 &lt;item&gt;
@@ -32,7 +32,7 @@
   &lt;dc:date&gt;${thing._date.isoformat()}&lt;/dc:date&gt;
   &lt;description&gt;
     &amp;lt;a href=&quot;${thing.url}&quot;&amp;gt;[link]&amp;lt;/a&amp;gt;
-    &amp;lt;a href=&quot;http://${request.host}${reddit_link(thing.permalink, url=True)}&quot;&amp;gt;[comments]&amp;lt;/a&amp;gt;
+    &amp;lt;a href=&quot;http://${request.host}${add_sr(thing.permalink, nocname=True)}&quot;&amp;gt;[comments]&amp;lt;/a&amp;gt;
   &lt;/description&gt;
 &lt;/item&gt;
 </diff>
      <filename>r2/r2/templates/link.xml</filename>
    </modified>
    <modified>
      <diff>@@ -17,10 +17,11 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
-&lt;% from r2.lib.template_helpers import replace_render, reddit_link %&gt;
+&lt;% from r2.lib.template_helpers import replace_render, add_sr %&gt;
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot; /&gt;
 
 &lt;%
    _id = (&quot;_%s&quot; % thing.parent_name) if hasattr(thing, 'parent_name') else ''
@@ -37,13 +38,13 @@
 %if thing.nextprev and (thing.prev or thing.next):
   &lt;p class=&quot;nextprev&quot;&gt; ${_(&quot;view more:&quot;)}&amp;#32;
   %if thing.prev:
-    &lt;a rel=&quot;nofollow,prev&quot; href=&quot;${reddit_link(thing.prev, url = True)}&quot;&gt;${_(&quot;prev&quot;)}&lt;/a&gt;
+    ${plain_link(_(&quot;prev&quot;), thing.prev, rel=&quot;nofollow,prev&quot;)}  
   %endif
   %if thing.prev and thing.next:
     &amp;#32;|&amp;#32;
   %endif
   %if thing.next:
-    &lt;a rel=&quot;nofollow,next&quot; href=&quot;${reddit_link(thing.next, url = True)}&quot;&gt;${_(&quot;next&quot;)}&lt;/a&gt;
+    ${plain_link(_(&quot;next&quot;), thing.next, rel=&quot;nofollow,prev&quot;)}  
   %endif
   &lt;/p&gt;
 %endif</diff>
      <filename>r2/r2/templates/listing.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,10 +17,11 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
-&lt;% from r2.lib.template_helpers import replace_render, reddit_link %&gt;
+&lt;% from r2.lib.template_helpers import replace_render, add_sr %&gt;
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot; /&gt;
 
 &lt;ul&gt;
 %for a in thing.things:
@@ -31,13 +32,13 @@
 %if thing.nextprev and (thing.prev or thing.next):
   &lt;p class=&quot;nextprev&quot;&gt; ${_(&quot;view more:&quot;)}&amp;#32;
   %if thing.prev:
-    &lt;a href=&quot;${reddit_link(thing.prev, url = True)}&quot;&gt;${_(&quot;prev&quot;)}&lt;/a&gt;
+    ${plain_link(_(&quot;prev&quot;), thing.prev)}  
   %endif
   %if thing.prev and thing.next:
     &amp;#32;|&amp;#32;
   %endif
   %if thing.next:
-    &lt;a rel=&quot;nofollow&quot; href=&quot;${reddit_link(thing.next, url = True)}&quot;&gt;${_(&quot;next&quot;)}&lt;/a&gt;
+    ${plain_link(_(&quot;next&quot;), thing.next)}  
   %endif
   &lt;/p&gt;
 %endif</diff>
      <filename>r2/r2/templates/listing.mobile</filename>
    </modified>
    <modified>
      <diff>@@ -17,20 +17,21 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot; /&gt;
 
 &lt;%def name=&quot;plain(selected = False)&quot;&gt;
   ${plain_link(thing.selected_title() if selected else thing.title, 
-               thing.path, _sr_path = thing.sr_path, 
+               thing.path, _sr_path = thing.sr_path, nocname = thing.nocname,
+               target = thing.target, 
                _class = thing.css_class, _id = thing._id)}
 &lt;/%def&gt;
 
 &lt;%def name=&quot;js(selected = False)&quot;&gt;
   ${plain_link(thing.selected_title() if selected else thing.title, 
-               '/', _sr_path = False,  
+               '/', _sr_path = False, nocname = thing.nocname, 
                _class = thing.css_class, _id = thing._id, onclick = thing.onclick)}
 &lt;/%def&gt;
 </diff>
      <filename>r2/r2/templates/navbutton.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link, text_with_links, img_link, separator&quot;/&gt;</diff>
      <filename>r2/r2/templates/navmenu.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,18 +17,20 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot;/&gt;
+
 &lt;%def name=&quot;subreddit()&quot;&gt;
   &lt;span class=&quot;hover pagename redditname&quot;&gt;
-    &lt;a href=&quot;${c.site.path}&quot;&gt;${c.site.name}&lt;/a&gt;
+    ${plain_link(c.site.name, c.site.path, _sr_path=False)}
   &lt;/span&gt;
 &lt;/%def&gt;
 
 &lt;%def name=&quot;reddits()&quot;&gt;
   &lt;span class=&quot;hover pagename redditname&quot;&gt;
-    &lt;a href=&quot;/reddits/&quot;&gt;${_(&quot;reddits&quot;)}&lt;/a&gt;
+    ${plain_link(_(&quot;reddits&quot;), &quot;/reddits/&quot;, _sr_path=False)}
   &lt;/span&gt;
 &lt;/%def&gt;
 
@@ -37,5 +39,5 @@
 &lt;/%def&gt;
 
 &lt;%def name=&quot;newpagelink()&quot;&gt;
-&lt;span class=&quot;newpagelink&quot;&gt;reddit all?&amp;#32;&lt;a href=&quot;/new/&quot;&gt;click here to find new links.&lt;/a&gt;&lt;/span&gt;
+&lt;span class=&quot;newpagelink&quot;&gt;reddit all?&amp;#32;${plain_link(&quot;click here to find new links.&quot;, &quot;/new/&quot;, _sr_path=False)}&lt;/span&gt;
 &lt;/%def&gt;</diff>
      <filename>r2/r2/templates/pagenamenav.html</filename>
    </modified>
    <modified>
      <diff>@@ -19,8 +19,7 @@
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
 ## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
-
-&lt;%namespace file=&quot;utils.html&quot; import=&quot;language_tool, language_checkboxes&quot;/&gt;
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;language_tool, language_checkboxes, plain_link&quot;/&gt;
 
 &lt;%def name=&quot;checkbox(text, name)&quot;&gt;
     &lt;input name=&quot;${name}&quot; id=&quot;${name}&quot; type=&quot;checkbox&quot;\
@@ -60,10 +59,15 @@
 %endif
 
 &lt;%
+   if c.cname:
+       param = &quot;?cnameframe=1&quot;
+   else:
+       param = &quot;&quot;
+
    if c.user_is_loggedin:
-       action = &quot;/post/options&quot;
+       action = &quot;/post/options&quot; + param
    else:
-       action = &quot;/post/unlogged_options&quot;
+       action = &quot;/post/unlogged_options&quot; + param
  %&gt;
 &lt;form action=&quot;${action}&quot; method=&quot;post&quot; class=&quot;pretty-form short-text&quot;&gt;
 &lt;input type=&quot;hidden&quot; name=&quot;uh&quot; value=&quot;${c.modhash}&quot; /&gt;
@@ -75,7 +79,7 @@
       ${language_tool(allow_blank = False, show_regions = True,
                       default_lang = c.user.pref_lang)}
       &amp;#32;&lt;span class=&quot;little gray hover&quot;&gt;(*) ${_(&quot;incomplete&quot;)}
-        &amp;#32;&lt;a href=&quot;/feedback&quot;&gt;${_(&quot;volunteer to translate&quot;)}&lt;/a&gt;&lt;/span&gt;
+      &amp;#32;${plain_link(_(&quot;volunteer to translate&quot;), &quot;/feedback&quot;)}&lt;/span&gt;
     &lt;/td&gt;
   &lt;/tr&gt;
   &lt;tr&gt;
@@ -156,7 +160,12 @@
   &amp;#32;&lt;span class=&quot;little gray&quot;&gt;(1 - ${g.max_comments})&lt;/span&gt;
     &lt;/td&gt;
   &lt;/tr&gt;
-  
+  &lt;tr&gt;
+    &lt;th&gt;${_(&quot;display options&quot;)}&lt;/th&gt;
+    &lt;td class=&quot;prefright&quot;&gt;
+      ${checkbox(_(&quot;allow reddits to show me custom styles&quot;), &quot;show_stylesheets&quot;)}
+    &lt;/td&gt;
+  &lt;/tr&gt;
   &lt;tr&gt;
     &lt;th&gt;${_(&quot;privacy options&quot;)}&lt;/th&gt;
     &lt;td class=&quot;prefright&quot;&gt;</diff>
      <filename>r2/r2/templates/prefoptions.html</filename>
    </modified>
    <modified>
      <diff>@@ -21,10 +21,12 @@
 ################################################################################
 
 &lt;%! 
-   from r2.lib.template_helpers import reddit_link 
+   from r2.lib.template_helpers import add_sr
    from r2.lib.strings import strings
 %&gt;
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot; /&gt;
+
 ${self.RenderPrintable()}
 
 &lt;%def name=&quot;admintagline()&quot;&gt;
@@ -148,7 +150,7 @@ ${self.RenderPrintable()}
        elif gray:
           author_cls += &quot; gray&quot;
        name = websafe(author.name)
-       href = unsafe('href=&quot;/user/%s/&quot;' % name)
+       href = unsafe('href=&quot;%s&quot;' % add_sr(&quot;/user/%s/&quot; % name, sr_path = False))
        if c.user_is_admin: name += &quot; (%d)&quot; % (author.link_karma)
     %&gt;
     &lt;a id=&quot;author_${thing._fullname}&quot; class=&quot;${author_cls}&quot; ${href}&gt;${name}&lt;/a&gt;
@@ -270,16 +272,15 @@ ${k.strip('_')}=&quot;${v}&quot; \
 ### originally in commentbutton
 &lt;%def name=&quot;comment_button(name, fullname, link_text, num, link,\
             a_class='', title='', newwindow = False)&quot;&gt;
-  &lt;% cls = &quot;&quot; if num == 0 else &quot;comments&quot; %&gt;
-  &lt;a href=&quot;${reddit_link(link, url = True)}&quot; 
-     id=&quot;${name}_${fullname}&quot; class=&quot;${a_class} ${cls}&quot; 
-     title=&quot;${title}&quot;
-     target=&quot;${'_blank' if newwindow else '_parent'}&quot; &gt;
-    %if num &gt; 0:
-      ${strings.number_label % (num,link_text)}\
-    %else:
-      ${link_text}\
-    %endif
-  &lt;/a&gt;
+  &lt;% 
+     cls = &quot;&quot; if num == 0 else &quot;comments&quot;
+
+     if num &gt; 0:
+         link_text = strings.number_label % (num, link_text)
+
+     target = '_blank' if newwindow else '_parent'
+  %&gt;
+  ${plain_link(link_text, link, id=&quot;%s_%s&quot; % (name, fullname), _class=&quot;%s %s&quot; % (a_class, cls), title=title, target=target)}
+
 &lt;/%def&gt;
 </diff>
      <filename>r2/r2/templates/printable.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-## &quot;The contents of this file are subject to the Common Public Attribution
+## The contents of this file are subject to the Common Public Attribution
 ## License Version 1.0. (the &quot;License&quot;); you may not use this file except in
 ## compliance with the License. You may obtain a copy of the License at
 ## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
@@ -17,14 +17,14 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%! 
    from r2.lib.filters import edit_comment_filter, unsafe, safemarkdown
    from r2.lib.utils import timesince
  %&gt;
-&lt;%namespace file=&quot;utils.html&quot; import=&quot;submit_form&quot;/&gt;
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;submit_form, plain_link&quot;/&gt;
 &lt;% user = thing.user %&gt;
 %if thing.user:
 &lt;div class=&quot;raisedbox&quot;&gt;
@@ -65,9 +65,7 @@
 
     %if c.user_is_loggedin and not thing.isMe:
     &lt;li&gt;
-      &lt;a href=&quot;/message/compose/?to=${thing.user.name}&quot;&gt;
-        ${_(&quot;send message&quot;)}
-      &lt;/a&gt;
+      ${plain_link(_(&quot;send message&quot;), &quot;/message/compose/?to=%s&quot; % thing.user.name)}
     &lt;/li&gt;
     &lt;li&gt;
       &lt;form action=&quot;/post/friend&quot; method=&quot;post&quot;&gt;</diff>
      <filename>r2/r2/templates/profilebar.html</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,7 @@
 ################################################################################
 
 &lt;%! 
-   from r2.lib.template_helpers import reddit_link, static, join_urls, class_dict, path_info
+   from r2.lib.template_helpers import add_sr, static, join_urls, class_dict, path_info
    from r2.lib.pages import SearchForm
    from pylons import request
 %&gt;
@@ -52,9 +52,16 @@
   %else:
     &lt;link rel=&quot;stylesheet&quot; href=&quot;${static(g.stylesheet)}&quot; 
           type=&quot;text/css&quot; /&gt;
-    %if c.site.stylesheet:
-    &lt;link rel=&quot;stylesheet&quot; href=&quot;${static(c.site.stylesheet)}&quot; 
-          type=&quot;text/css&quot; /&gt;
+    %if (not g.css_killswitch) and c.user.pref_show_stylesheets:
+      %if c.site.stylesheet:
+      &lt;link rel=&quot;stylesheet&quot; href=&quot;${static(c.site.stylesheet)}&quot; 
+            type=&quot;text/css&quot; /&gt;
+      %endif
+      %if c.site.stylesheet_contents:
+      &lt;link rel=&quot;stylesheet&quot; href=&quot;${c.site.path}stylesheet?v=${c.site.stylesheet_hash}&quot;
+            title=&quot;applied_subreddit_stylesheet&quot;
+            type=&quot;text/css&quot; /&gt;
+      %endif
     %endif
   %endif
 
@@ -62,7 +69,7 @@
         type=&quot;image/x-icon&quot; /&gt;
   %if thing.extension_handling:
     &lt;link rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot; title=&quot;RSS&quot;
-          href=&quot;${reddit_link(join_urls(request.path,'.rss'), url=True)}&quot; /&gt;
+          href=&quot;${add_sr(join_urls(request.path,'.rss'))}&quot; /&gt;
   %endif
 &lt;/%def&gt;
 </diff>
      <filename>r2/r2/templates/reddit.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%!
@@ -32,13 +32,13 @@
   ${thing.footer_nav().render()}
 
   &lt;p class=&quot;wired&quot;&gt;
-    &lt;a rel=&quot;nofollow&quot; href=&quot;http://wired.com&quot;&gt;
+    &lt;a rel=&quot;nofollow&quot; target=&quot;_top&quot; href=&quot;http://wired.com&quot;&gt;
       &lt;img src=&quot;${static('wired_w.png')}&quot; alt=&quot;wired&quot; /&gt;&lt;/a&gt;
-    &lt;a rel=&quot;nofollow&quot; href=&quot;http://wired.com&quot;&gt;WIRED.com&lt;/a&gt;-
-    &lt;a rel=&quot;nofollow&quot; href=&quot;http://howto.wired.com&quot;&gt;WIRED How-To&lt;/a&gt;
+    &lt;a rel=&quot;nofollow&quot; target=&quot;_top&quot; href=&quot;http://wired.com&quot;&gt;WIRED.com&lt;/a&gt;-
+    &lt;a rel=&quot;nofollow&quot; target=&quot;_top&quot; href=&quot;http://howto.wired.com&quot;&gt;WIRED How-To&lt;/a&gt;
   &lt;/p&gt;
   &lt;p class=&quot;bottommenu&quot;&gt;
-    ${text_with_links(_(&quot;Use of this site constitutes acceptance of our %(user_agreement)s and %(privacy_policy)s&quot;), user_agreement= (_(&quot;User Agreement {Genitive}&quot;), &quot;http://reddit.com/help/useragreement&quot;), privacy_policy = (_(&quot;Privacy Policy {Genitive}&quot;), &quot;http://reddit.com/help/privacypolicy&quot;))}.  
+    ${text_with_links(_(&quot;Use of this site constitutes acceptance of our %(user_agreement)s and %(privacy_policy)s&quot;), nocname=True, user_agreement= (_(&quot;User Agreement {Genitive}&quot;), &quot;http://reddit.com/help/useragreement&quot;), privacy_policy = (_(&quot;Privacy Policy {Genitive}&quot;), &quot;http://reddit.com/help/privacypolicy&quot;))}.  
     &lt;% old = _(&quot;(c) 2008 CondeNet, Inc. All rights reserved.&quot;) %&gt;
     ${_(&quot;(c) %(year)d CondeNet, Inc. All rights reserved.&quot;) % \
     dict(year=2008)}</diff>
      <filename>r2/r2/templates/redditfooter.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-## &quot;The contents of this file are subject to the Common Public Attribution
+## The contents of this file are subject to the Common Public Attribution
 ## License Version 1.0. (the &quot;License&quot;); you may not use this file except in
 ## compliance with the License. You may obtain a copy of the License at
 ## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
@@ -23,6 +23,7 @@
 &lt;%!
    from r2.lib.template_helpers import static
    from r2.models import Sub, FakeSubreddit
+   from r2.models.subreddit import DefaultSR
    from r2.lib.pages import SearchForm
 %&gt;
 &lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link, text_with_js, img_link, separator&quot;/&gt;
@@ -60,9 +61,13 @@
   &lt;/div&gt;
 
   &lt;div id=&quot;header-bottom-${'right' if c.lang_rtl else 'left'}&quot;&gt;
-    &lt;a href=&quot;/&quot;&gt;
-      &lt;img id=&quot;header-img&quot; src=&quot;${c.site.header}&quot; alt=&quot;${c.site.name}&quot; /&gt;
-    &lt;/a&gt;
+    &lt;%
+        if g.css_killswitch or not c.site.header:
+            header_img = DefaultSR.header
+        else:
+            header_img = c.site.header
+    %&gt;
+    ${img_link(c.site.name, header_img, '/', _id = &quot;header-img-a&quot;, img_id = 'header-img')}
 
     ##keeps the height of the header from varying when there isnt any content
     &amp;nbsp;</diff>
      <filename>r2/r2/templates/redditheader.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,14 +17,14 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%!
-   from r2.lib.template_helpers import reddit_link, static
+   from r2.lib.template_helpers import add_sr, static
 %&gt;
 
-&lt;form action=&quot;${reddit_link('/search', url=True)}&quot; id=&quot;search&quot;&gt;
+&lt;form action=&quot;${add_sr('/search')}&quot; id=&quot;search&quot;&gt;
   &lt;input type=&quot;text&quot; 
          %if thing.prev_search:
            value=&quot;${thing.prev_search}&quot; style=&quot;color:black&quot;</diff>
      <filename>r2/r2/templates/searchform.html</filename>
    </modified>
    <modified>
      <diff>@@ -30,7 +30,7 @@ http://${g.domain}/goto?share=true&amp;id=${thing.link._fullname}
 
 &lt;% from r2.lib.strings import strings, plurals %&gt;${_(&quot;There are currently %(num_comments)s on this link.  You can view them here:&quot;) % dict(num_comments = strings.number_label % (thing.link.num_comments, plurals.N_comments(thing.link.num_comments)))}
 
-&lt;% from r2.lib.template_helpers import reddit_link %&gt;http://${g.domain}${reddit_link(thing.link.permalink, url=True)}
+&lt;% from r2.lib.template_helpers import add_sr %&gt;http://${g.domain}${add_sr(thing.link.permalink, url=True)}
 
 ___
 If you would not like to receive emails from reddit.com in the future, visit http://${g.domain}/mail/optout?x=${thing.msg_hash}
\ No newline at end of file</diff>
      <filename>r2/r2/templates/share.email</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,8 @@
           &lt;/label&gt;
         &lt;/th&gt;
         &lt;td&gt;
-          &lt;textarea id=&quot;share_to_${thing.link_name}&quot; name=&quot;share_to&quot; rows=&quot;4&quot;&gt;
+          &lt;textarea id=&quot;share_to_${thing.link_name}&quot; 
+                    name=&quot;share_to&quot; rows=&quot;4&quot; cols=&quot;40&quot;&gt;
             ${unsafe('&amp;#x0D;&amp;#x0A;'.join(websafe(e) for e in thing.emails))}
           &lt;/textarea&gt;
         &lt;/td&gt;
@@ -55,7 +56,7 @@
           &lt;/span&gt;
         &lt;/th&gt;
         &lt;td&gt;
-          &lt;input name=&quot;replyto&quot; type=&quot;text&quot; size=&quot;30&quot;
+          &lt;input name=&quot;replyto_${thing.link_name}&quot; type=&quot;text&quot; size=&quot;30&quot;
                  value=&quot;${c.user.email if hasattr(c.user, 'email') else ''}&quot;/&gt;
         &lt;/td&gt;
         &lt;td&gt;
@@ -74,7 +75,7 @@
           &lt;/span&gt;
         &lt;/th&gt;
         &lt;td&gt;
-          &lt;textarea id=&quot;message_${thing.link_name}&quot; name=&quot;message&quot; rows=&quot;4&quot;&gt;
+          &lt;textarea id=&quot;message_${thing.link_name}&quot; name=&quot;message&quot; rows=&quot;4&quot; cols=&quot;40&quot;&gt;
             ${c.user.name} from http://${g.domain}/ has shared a link with you.
           &lt;/textarea&gt;
         &lt;/td&gt;</diff>
      <filename>r2/r2/templates/sharelink.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,15 +17,21 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot;/&gt;
+
 &lt;div class=&quot;sidebox ${thing.css_class}&quot;&gt;
-  &lt;a class=&quot;morelink&quot;
-     %if not c.user_is_loggedin and thing.show_cover:
-       onclick=&quot;return(showcover(true, 'redirect_${thing.link}'));&quot;
-     %endif
-     href=&quot;${thing.link}&quot;&gt;${thing.title} &amp;raquo;&lt;/a&gt;
+  &lt;%
+     if not c.user_is_loggedin and thing.show_cover:
+         onclick=&quot;return(showcover(true, 'redirect_%s'));&quot; % thing.link
+     else:
+         onclick = None
+
+     nocname = thing.nocname
+  %&gt;
+  ${plain_link(thing.title,thing.link, _sr_path = False, _class=&quot;morelink&quot;, onclick=onclick, nocname=nocname)}
   %if thing.subtitles:
     &lt;div class=&quot;spacer&quot;&gt;
       %for subtitle in thing.subtitles:</diff>
      <filename>r2/r2/templates/sidebox.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%!
@@ -25,6 +25,8 @@
    %&gt;
 &lt;%inherit  file=&quot;printable.html&quot;/&gt;
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot;/&gt;
+
 &lt;%def name=&quot;numcol()&quot;&gt;
 &lt;/%def&gt;
 
@@ -32,9 +34,7 @@
 &lt;%def name=&quot;entry()&quot;&gt;
 &lt;% fullname = thing._fullname %&gt;
 &lt;p class=&quot;titlerow&quot;&gt;
-  &lt;a id=&quot;title_${fullname}&quot; class=&quot;title&quot; href=&quot;${thing.path}&quot;&gt;
-    ${thing.title} 
-  &lt;/a&gt;
+  ${plain_link(thing.title, thing.path, _class=&quot;title&quot;, _id=&quot;title_%s&quot; % fullname)}
   &lt;span class=&quot;domain&quot;&gt;(${thing.path})&lt;/span&gt; 
   %if c.user_is_admin:
   ${self.admintagline()}</diff>
      <filename>r2/r2/templates/subreddit.html</filename>
    </modified>
    <modified>
      <diff>@@ -25,6 +25,8 @@
    %&gt;
 &lt;%inherit  file=&quot;printable.mobile&quot;/&gt;
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot;/&gt;
+
 &lt;%def name=&quot;numcol()&quot;&gt;
 &lt;/%def&gt;
 
@@ -32,9 +34,7 @@
 &lt;%def name=&quot;entry()&quot;&gt;
 &lt;% fullname = thing._fullname %&gt;
 &lt;p&gt;
-  &lt;a class=&quot;title&quot; href=&quot;${thing.path}&quot;&gt;
-    ${thing.title} 
-  &lt;/a&gt;
+  ${plain_link(thing.title, thing.path, _class=&quot;title&quot;)}
   &lt;span class=&quot;domain&quot;&gt;(${thing.path})&lt;/span&gt; 
 &lt;/p&gt;
 %if thing.description:</diff>
      <filename>r2/r2/templates/subreddit.mobile</filename>
    </modified>
    <modified>
      <diff>@@ -17,8 +17,9 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot;/&gt;
 
 &lt;div class=&quot;subredditbox&quot;&gt;
    &lt;form method=&quot;post&quot; action=&quot;/post/subscriptions&quot; id=&quot;sr_subscriptions&quot;
@@ -50,7 +51,13 @@
                        onchange=&quot;return change_sr('${sr._fullname}');&quot; 
                        id=&quot;sr_sel_chx_${sr._fullname}&quot;/&gt;
               %endif
-              &lt;a href=&quot;${sr.path or '/'}&quot;&gt;${sr.name}&lt;/a&gt;
+              &lt;%
+                 if sr.path:
+                     path = sr.path
+                 else:
+                     path = '/'
+              %&gt;
+              ${plain_link(sr.name, path, _sr_path=False, nocname=True)}   
             &lt;/li&gt;
           %endfor
         &lt;/ul&gt;
@@ -58,7 +65,6 @@
     %endfor
     &lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;
   &lt;/form&gt;
-  &lt;a class=&quot;morelink&quot; href=&quot;/reddits/&quot;&gt;
-    ${_(&quot;more&quot;)} &amp;raquo;
-  &lt;/a&gt;
+  ${plain_link(unsafe('%s &amp;raquo;' % _(&quot;more&quot;)), &quot;/reddits/&quot;, _class=&quot;morelink&quot;, 
+   fmt='%s', _sr_path=False, nocname=True)}
 &lt;/div&gt;</diff>
      <filename>r2/r2/templates/subredditbox.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;% </diff>
      <filename>r2/r2/templates/translatedstring.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%</diff>
      <filename>r2/r2/templates/translation.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,15 +17,17 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
+&lt;%namespace file=&quot;utils.html&quot; import=&quot;plain_link&quot;/&gt;
+
 ##&lt;h1&gt;awards&lt;/h1&gt;
 ##&lt;table class='stats'&gt;
 ##&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;th&gt;today&lt;/th&gt;&lt;/tr&gt;
 ###for a in $awards
 ##    #set u = $user_objs[a[&quot;uid&quot;]]
-##    &lt;tr&gt;&lt;td class='ri' style=&quot;padding-right: 10px&quot;&gt;$a['award']&lt;/td&gt;&lt;td class='k'&gt;&lt;a href=&quot;/user/$u.name/&quot;&gt;$u.name&lt;/a&gt; ($sanekarma($u.pop))&lt;/td&gt;&lt;/tr&gt;
+##    &lt;tr&gt;&lt;td class='ri' style=&quot;padding-right: 10px&quot;&gt;$a['award']&lt;/td&gt;&lt;td class='k'&gt;${plain_link(u.name, &quot;/user/%s&quot; % u.name)} ($sanekarma($u.pop))&lt;/td&gt;&lt;/tr&gt;
 ###end for
 ##&lt;/table&gt;
 ###end if
@@ -36,7 +38,7 @@
   &lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;${_(&quot;today&quot;)}&lt;/th&gt;&lt;/tr&gt;
   %for user, change in thing.top_day:
     &lt;tr&gt;
-      &lt;td class=&quot;k&quot;&gt;&lt;a href=&quot;/user/${user.name}/&quot;&gt;${user.name}&lt;/a&gt; (${user.link_karma})&lt;/td&gt;
+      &lt;td class=&quot;k&quot;&gt;${plain_link(user.name, &quot;/user/%s&quot; % user.name)} (${user.link_karma})&lt;/td&gt;
       &lt;td class=&quot;ri&quot;&gt;+${change}&lt;/td&gt;
     &lt;/tr&gt;
   %endfor
@@ -46,7 +48,7 @@
   &lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;${_(&quot;this week&quot;)}&lt;/th&gt;&lt;/tr&gt;
   %for user, change in thing.top_week:
   &lt;tr&gt;
-    &lt;td class=&quot;k&quot;&gt;&lt;a href=&quot;/user/${user.name}/&quot;&gt;${user.name}&lt;/a&gt; (${user.link_karma})&lt;/td&gt;
+    &lt;td class=&quot;k&quot;&gt;${plain_link(user.name, &quot;/user/%s&quot; % user.name)} (${user.link_karma})&lt;/td&gt;
     &lt;td class=&quot;ri&quot;&gt;+${change}&lt;/td&gt;
   &lt;/tr&gt;
   %endfor
@@ -56,7 +58,7 @@
   &lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;${_(&quot;all-time&quot;)}&lt;/th&gt;&lt;/tr&gt;
   %for user in thing.top_users:
     &lt;tr&gt;
-      &lt;td class=&quot;k&quot;&gt;&lt;a href=&quot;/user/${user.name}/&quot;&gt;${user.name}&lt;/a&gt; (${user.link_karma})&lt;/td&gt;
+      &lt;td class=&quot;k&quot;&gt;${plain_link(user.name, &quot;/user/%s&quot; % user.name)} (${user.link_karma})&lt;/td&gt;
     &lt;/tr&gt;
   %endfor
 &lt;/table&gt;</diff>
      <filename>r2/r2/templates/userstats.html</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.
+## CondeNet, Inc. All Rights Reserved.&quot;
 ################################################################################
 
 &lt;%namespace file=&quot;printable.html&quot; import=&quot;yes_no_button&quot; /&gt;
@@ -39,7 +39,7 @@
          &amp;nbsp;(&lt;b&gt;${thing.user.safe_karma}&lt;/b&gt;)
       &lt;/span&gt;&amp;nbsp;
   %elif c.user_is_loggedin and name == &quot;sendmessage&quot; and c.user != thing.user:
-    &lt;a href=&quot;/message/compose?to=${thing.user.name}&quot;&gt;${_(&quot;send message&quot;)}&lt;/a&gt;&amp;nbsp;
+    ${plain_link(_(&quot;send message&quot;), &quot;/message/compose?to=%s&quot; % (thing.user.name))}&amp;nbsp;
   %elif name == &quot;remove&quot; and thing.editable:
     ${yes_no_button(&quot;remove&quot;, thing.name, _(&quot;remove&quot;),
     &quot;return deletetoggle(this, UserTable.del('%s', '%s'));&quot;</diff>
      <filename>r2/r2/templates/usertableitem.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-## &quot;The contents of this file are subject to the Common Public Attribution.
+## The contents of this file are subject to the Common Public Attribution.
 ## License Version 1.0. (the &quot;License&quot;); you may not use this file except in
 ## compliance with the License. You may obtain a copy of the License at
 ## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
@@ -17,13 +17,13 @@
 ## the Original Code is CondeNet, Inc.
 ## 
 ## All portions of the code written by CondeNet are Copyright (c) 2006-2008
-## CondeNet, Inc. All Rights Reserved.&quot;
+## CondeNet, Inc. All Rights Reserved.
 ################################################################################
 
 &lt;%!
    from r2.controllers.errors import errors
-   from r2.lib.filters import spaceCompress
-   from r2.lib.template_helpers import reddit_link
+   from r2.lib.filters import spaceCompress, unsafe
+   from r2.lib.template_helpers import add_sr
    from r2.lib.utils import cols
 %&gt;
 &lt;%def name=&quot;tags(**kw)&quot;&gt;
@@ -94,23 +94,42 @@ ${errors.get(name).message}
 &lt;/script&gt;
 &lt;/%def&gt;
 
-&lt;%def name=&quot;img_link(title, img, path, _id='', **kw)&quot;&gt;
+&lt;%def name=&quot;img_link(link_text, img, path, _id='', target='', img_id = None, **kw)&quot;&gt;
+  &lt;% 
+     if (not target or target == '_parent') and c.cname:
+         target = '_top'
+     if target:
+         kw['target'] = target
+
+     path = add_sr(path, sr_path = False)
+     kw['target'] = target
+  %&gt;
   &lt;%call expr=&quot;_a(href=path, _id=_id, **kw)&quot;&gt;
-    &lt;img src=&quot;${img}&quot; alt=&quot;${title}&quot;/&gt;
+    &lt;img ${(&quot;id='%s'&quot; % img_id) if img_id else ''} src=&quot;${img}&quot; alt=&quot;${link_text}&quot;/&gt;
   &lt;/%call&gt;
 &lt;/%def&gt;
 
-&lt;%def name=&quot;plain_link(title, path, _sr_path = True, fmt='', **kw)&quot;&gt;
-  &lt;% link = _a_buffered(title, href=reddit_link(path, url=_sr_path), **kw) %&gt;
+&lt;%def name=&quot;plain_link(link_text, path, _sr_path = True, nocname=False, fmt='', target='', **kw)&quot;&gt;
+  &lt;% 
+     if (not target or target == '_parent') and c.cname:
+         target = '_top'
+     if c.cname and path.startswith('http://'):
+         target = '_top'
+     if target:
+         kw['target'] = target
+
+     link = _a_buffered(link_text, href=add_sr(path, sr_path=_sr_path, nocname=nocname), **kw) 
+  %&gt;
+
   ${unsafe((fmt % link) if fmt else link)}
 &lt;/%def&gt;
 
 
-&lt;%def name=&quot;text_with_links(txt, _sr_path = False, **kw)&quot;&gt;
+&lt;%def name=&quot;text_with_links(txt, _sr_path = False, nocname=False, **kw)&quot;&gt;
 &lt;%
    from r2.lib.filters import _force_unicode
    for key, (text, href) in kw.iteritems():
-      kw[key]=spaceCompress(capture(plain_link, text, href, _sr_path=_sr_path))
+      kw[key]=spaceCompress(capture(plain_link, text, href, _sr_path=_sr_path, nocname=nocname))
    txt = _force_unicode(txt) % kw
    txt = txt.replace(&quot; &lt;&quot;, &quot;&amp;#32;&lt;&quot;).replace(&quot;&gt; &quot;, &quot;&gt;&amp;#32;&quot;)
 </diff>
      <filename>r2/r2/templates/utils.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-## &quot;The contents of this file are subject to the Common Public Attribution
+## The contents of this file are subject to the Common Public Attribution
 ## License Version 1.0. (the &quot;License&quot;); you may not use this file except in
 ## compliance with the License. You may obtain a copy of the License at
 ## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
@@ -21,7 +21,9 @@
 ################################################################################
 
 &lt;script type=&quot;text/javascript&quot;&gt;
-
+&lt;%
+   domain = c.site.domain if c.cname else c.domain
+ %&gt;
 function escapeHTML(text) {
   var div = document.createElement('div');
   var text = document.createTextNode(text);
@@ -39,11 +41,11 @@ function update() {
     f = document.forms.widget;
     which = getrval(f.which);
     if (which == &quot;all&quot;) {
-        url = &quot;http://${c.domain}/&quot; + f.what.value + &quot;/.embed?limit=&quot; +
+        url = &quot;http://${domain}/&quot; + f.what.value + &quot;/.embed?limit=&quot; +
                       f.num.value + &quot;&amp;t=&quot; + f.when.value;
     } else if (which == &quot;one&quot;) {
         if (!f.who2.value) return;
-        url = &quot;http://${c.domain}/user/&quot;+f.who2.value+&quot;/&quot;+
+        url = &quot;http://${domain}/user/&quot;+f.who2.value+&quot;/&quot;+
                       f.where2.value+&quot;.embed?limit=&quot; + f.num.value + 
                       &quot;&amp;sort=&quot;+f.what2.value;
     } else {
@@ -67,7 +69,7 @@ function update() {
   &lt;div id=&quot;preview&quot;&gt;
     &lt;span&gt;preview&lt;/span&gt;
     &lt;div id=&quot;previewbox&quot;&gt;
-      &lt;script src=&quot;http://${c.domain}/.embed?limit=5&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
+      &lt;script src=&quot;http://${domain}/.embed?limit=5&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
     &lt;/div&gt;
   &lt;/div&gt;
 
@@ -139,7 +141,7 @@ function update() {
 
   &lt;p&gt;
     &lt;textarea rows=&quot;5&quot; cols=&quot;50&quot; id=&quot;codebox&quot;&gt;
-      &amp;lt;script src=&quot;http://${c.domain}/.embed?limit=5&quot; type=&quot;text/javascript&quot;&gt;&amp;lt;/script&gt;
+      &amp;lt;script src=&quot;http://${domain}/.embed?limit=5&quot; type=&quot;text/javascript&quot;&gt;&amp;lt;/script&gt;
     &lt;/textarea&gt;
   &lt;/p&gt;
 &lt;/div&gt;</diff>
      <filename>r2/r2/templates/widgetdemopanel.html</filename>
    </modified>
    <modified>
      <diff>@@ -83,6 +83,7 @@ setup(
                       &quot;simplejson&quot;, 
                       &quot;SQLAlchemy==0.3.10&quot;,
                       &quot;BeautifulSoup &gt;= 3&quot;,  
+                      &quot;cssutils&quot;,
                       &quot;chardet&quot;,
                       &quot;psycopg2&quot;,
                       &quot;py_interface&quot;],</diff>
      <filename>r2/setup.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1a107601fa490ca69215facceebe3d0dc5e7f1f8</id>
    </parent>
  </parents>
  <author>
    <name>ketralnis</name>
    <email>ketralnis@reddit.com</email>
  </author>
  <url>http://github.com/reddit/reddit/commit/6bcef0037bdb2d139a15065c3f31e872bae79df3</url>
  <id>6bcef0037bdb2d139a15065c3f31e872bae79df3</id>
  <committed-date>2008-08-26T07:15:02-07:00</committed-date>
  <authored-date>2008-08-26T07:15:02-07:00</authored-date>
  <message>1. Allow a reddit to have a cname, like www.proggit.com, that renders
   the listing for that reddit

2. Allow a reddit to have a custom CSS stylesheet that appears to
   visitors

3. Allow a reddit to upload a custom reddit alien logo</message>
  <tree>d5fdc8258508b7bc070b20713ac95a9f23ca38bb</tree>
  <committer>
    <name>ketralnis</name>
    <email>ketralnis@reddit.com</email>
  </committer>
</commit>
