Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (None, 'watson', None, '. ')
  LOAD_CONST <code add_scheduled_job>
  MAKE_FUNCTION defaults
  STORE_NAME add_scheduled_job
  RETURN_CONST None
END
CODE add_scheduled_job(self, text_source, cron_args, text_format, title, author, summary, synthesizer, synth_args, sentence_break)
  DOC 'pass'
  MAKE_CELL self
  MAKE_CELL text_source
  MAKE_CELL text_format
  MAKE_CELL title
  MAKE_CELL author
  MAKE_CELL summary
  MAKE_CELL synthesizer
  MAKE_CELL synth_args
  MAKE_CELL sentence_break
  RESUME 0
  LOAD_GLOBAL NULL + callable
  LOAD_DEREF text_source
  CALL 1
  POP_JUMP_IF_TRUE L1
  LOAD_GLOBAL NULL + TypeError
  LOAD_CONST 'Argument "text" must be a function'
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_CLOSURE author
  LOAD_CLOSURE self
  LOAD_CLOSURE sentence_break
  LOAD_CLOSURE summary
  LOAD_CLOSURE synth_args
  LOAD_CLOSURE synthesizer
  LOAD_CLOSURE text_format
  LOAD_CLOSURE text_source
  LOAD_CLOSURE title
  BUILD_TUPLE 9
  LOAD_CONST <code add_scheduled_job.<locals>.add_episode>
  MAKE_FUNCTION closure
  STORE_FAST add_episode
  PUSH_NULL
  LOAD_DEREF self
  LOAD_ATTR _scheduler
  LOAD_ATTR add_job
  LOAD_FAST add_episode
  LOAD_CONST 'cron'
  BUILD_TUPLE 2
  LOAD_CONST 'id'
  LOAD_DEREF title
  BUILD_MAP 1
  LOAD_FAST cron_args
  DICT_MERGE 1
  CALL_FUNCTION_EX 1
  LOAD_DEREF self
  LOAD_ATTR scheduled_jobs
  LOAD_DEREF title
  STORE_SUBSCR
  LOAD_DEREF self
  LOAD_ATTR _scheduler
  LOAD_ATTR running
  POP_JUMP_IF_TRUE L2
  LOAD_DEREF self
  LOAD_ATTR _scheduler
  LOAD_ATTR NULL|self + start
  CALL 0
  POP_TOP
  RETURN_CONST None
L2:
  RETURN_CONST None
END
CODE add_scheduled_job.<locals>.add_episode()
  COPY_FREE_VARS 9
  RESUME 0
  PUSH_NULL
  LOAD_DEREF text_source
  CALL 0
  STORE_FAST episode_text
  LOAD_DEREF title
  LOAD_CONST '_'
  BINARY_OP +
  LOAD_GLOBAL datetime
  LOAD_ATTR NULL|self + utcnow
  CALL 0
  LOAD_ATTR NULL|self + strftime
  LOAD_CONST '%Y%m%d%H%M%S'
  CALL 1
  BINARY_OP +
  STORE_FAST episode_title
  LOAD_DEREF self
  LOAD_ATTR NULL|self + add_episode
  LOAD_FAST episode_text
  LOAD_DEREF text_format
  LOAD_FAST episode_title
  LOAD_DEREF author
  LOAD_DEREF summary
  LOAD_GLOBAL datetime
  LOAD_ATTR NULL|self + utcnow
  CALL 0
  LOAD_DEREF synthesizer
  LOAD_DEREF synth_args
  LOAD_DEREF sentence_break
  CALL 9
  POP_TOP
  RETURN_CONST None
END

def add_scheduled_job(self, text_source, cron_args, text_format, title, author, summary=None, synthesizer='watson', synth_args=None, sentence_break='. '):
    """pass"""
    if not callable(text_source):
        raise TypeError('Argument "text" must be a function')

    def add_episode():
        episode_text = text_source()
        episode_title = title + '_' + datetime.utcnow().strftime('%Y%m%d%H%M%S')
        self.add_episode(episode_text, text_format, episode_title, author, summary, datetime.utcnow(), synthesizer, synth_args, sentence_break)
    self.scheduled_jobs[title] = self._scheduler.add_job(add_episode, 'cron', id=title, **cron_args)
    if not self._scheduler.running:
        self._scheduler.start()


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code publish>
  MAKE_FUNCTION 0
  STORE_NAME publish
  RETURN_CONST None
END
CODE publish(self, titles)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST titles
  LOAD_GLOBAL Sequence
  CALL 2
  POP_JUMP_IF_FALSE L3
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST titles
  LOAD_GLOBAL six
  LOAD_ATTR string_types
  CALL 2
  POP_JUMP_IF_TRUE L3
  LOAD_FAST titles
  GET_ITER
L1:
  FOR_ITER L2
  STORE_FAST title
  LOAD_FAST self
  LOAD_ATTR episodes
  LOAD_FAST title
  BINARY_SUBSCR
  LOAD_ATTR NULL|self + publish
  CALL 0
  POP_TOP
  JUMP_BACKWARD L1
L2:
  END_FOR
  JUMP_FORWARD L5
L3:
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST titles
  LOAD_GLOBAL six
  LOAD_ATTR string_types
  CALL 2
  POP_JUMP_IF_FALSE L4
  LOAD_FAST self
  LOAD_ATTR episodes
  LOAD_FAST titles
  BINARY_SUBSCR
  LOAD_ATTR NULL|self + publish
  CALL 0
  POP_TOP
  JUMP_FORWARD L5
L4:
  LOAD_GLOBAL NULL + TypeError
  LOAD_CONST 'titles must be a string or a sequence of strings.'
  CALL 1
  RAISE_VARARGS 1
L5:
  LOAD_FAST self
  LOAD_ATTR NULL|self + update_rss_feed
  CALL 0
  POP_TOP
  RETURN_CONST None
END

def publish(self, titles):
    """pass"""
    if isinstance(titles, Sequence) and (not isinstance(titles, six.string_types)):
        for title in titles:
            self.episodes[title].publish()
    elif isinstance(titles, six.string_types):
        self.episodes[titles].publish()
    else:
        raise TypeError('titles must be a string or a sequence of strings.')
    self.update_rss_feed()

code-search-net/code_search_net (python, train split)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code render_audio>
  MAKE_FUNCTION 0
  STORE_NAME render_audio
  RETURN_CONST None
END
CODE render_audio(self)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + text_to_speech
  LOAD_FAST self
  LOAD_ATTR _text
  LOAD_FAST self
  LOAD_ATTR synthesizer
  LOAD_FAST self
  LOAD_ATTR synth_args
  LOAD_FAST self
  LOAD_ATTR sentence_break
  CALL 4
  STORE_FAST segment
  LOAD_GLOBAL NULL + len
  LOAD_FAST segment
  CALL 1
  STORE_FAST milli
  LOAD_CONST '{0:.1f}'
  LOAD_ATTR NULL|self + format
  LOAD_GLOBAL NULL + float
  LOAD_FAST milli
  CALL 1
  LOAD_CONST 1000
  BINARY_OP /
  LOAD_CONST 60
  BINARY_OP %
  CALL 1
  LOAD_ATTR NULL|self + zfill
  LOAD_CONST 2
  CALL 1
  STORE_FAST seconds
  LOAD_CONST '{0:.0f}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST milli
  LOAD_CONST 60000
  BINARY_OP /
  LOAD_CONST 60
  BINARY_OP %
  CALL 1
  LOAD_ATTR NULL|self + zfill
  LOAD_CONST 2
  CALL 1
  STORE_FAST minutes
  LOAD_CONST '{0:.0f}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST milli
  LOAD_CONST 3600000
  BINARY_OP /
  LOAD_CONST 24
  BINARY_OP %
  CALL 1
  LOAD_ATTR NULL|self + zfill
  LOAD_CONST 2
  CALL 1
  STORE_FAST hours
  LOAD_FAST hours
  LOAD_CONST ':'
  BINARY_OP +
  LOAD_FAST minutes
  BINARY_OP +
  LOAD_CONST ':'
  BINARY_OP +
  LOAD_FAST seconds
  BINARY_OP +
  LOAD_FAST self
  STORE_ATTR duration
  LOAD_FAST segment
  LOAD_ATTR NULL|self + export
  LOAD_FAST self
  LOAD_ATTR link
  LOAD_CONST 'mp3'
  KW_NAMES ('format',)
  CALL 2
  POP_TOP
  LOAD_GLOBAL os
  LOAD_ATTR path
  LOAD_ATTR NULL|self + getsize
  LOAD_FAST self
  LOAD_ATTR link
  CALL 1
  LOAD_FAST self
  STORE_ATTR length
  RETURN_CONST None
END

def render_audio(self):
    """pass"""
    segment = text_to_speech(self._text, self.synthesizer, self.synth_args, self.sentence_break)
    milli = len(segment)
    seconds = '{0:.1f}'.format(float(milli) / 1000 % 60).zfill(2)
    minutes = '{0:.0f}'.format(milli / (1000 * 60) % 60).zfill(2)
    hours = '{0:.0f}'.format(milli / (1000 * 60 * 60) % 24).zfill(2)
    self.duration = hours + ':' + minutes + ':' + seconds
    segment.export(self.link, format='mp3')
    self.length = os.path.getsize(self.link)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code remove_exponent>
  MAKE_FUNCTION 0
  STORE_NAME remove_exponent
  RETURN_CONST None
END
CODE remove_exponent(d)
  DOC 'pass'
  RESUME 0
  LOAD_FAST d
  LOAD_FAST d
  LOAD_ATTR NULL|self + to_integral
  CALL 0
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L1
  LOAD_FAST d
  LOAD_ATTR NULL|self + quantize
  LOAD_GLOBAL NULL + Decimal
  LOAD_CONST 1
  CALL 1
  CALL 1
  RETURN_VALUE
L1:
  LOAD_FAST d
  LOAD_ATTR NULL|self + normalize
  CALL 0
  RETURN_VALUE
END

def remove_exponent(d):
    """pass"""
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST 0
  LOAD_CONST True
  BUILD_LIST 0
  BUILD_TUPLE 3
  LOAD_CONST <code millify>
  MAKE_FUNCTION defaults
  STORE_NAME millify
  RETURN_CONST None
END
CODE millify(n, precision, drop_nulls, prefixes)
  DOC 'pass'
  RESUME 0
  BUILD_LIST 0
  LOAD_CONST ('', 'k', 'M', 'B', 'T', 'P', 'E', 'Z', 'Y')
  LIST_EXTEND 1
  STORE_FAST millnames
  LOAD_FAST prefixes
  POP_JUMP_IF_FALSE L1
  LOAD_CONST ''
  BUILD_LIST 1
  STORE_FAST millnames
  LOAD_FAST millnames
  LOAD_ATTR NULL|self + extend
  LOAD_FAST prefixes
  CALL 1
  POP_TOP
L1:
  LOAD_GLOBAL NULL + float
  LOAD_FAST n
  CALL 1
  STORE_FAST n
  LOAD_GLOBAL NULL + max
  LOAD_CONST 0
  LOAD_GLOBAL NULL + min
  LOAD_GLOBAL NULL + len
  LOAD_FAST millnames
  CALL 1
  LOAD_CONST 1
  BINARY_OP -
  LOAD_GLOBAL NULL + int
  LOAD_GLOBAL math
  LOAD_ATTR NULL|self + floor
  LOAD_FAST n
  LOAD_CONST 0
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L2
  LOAD_CONST 0
  JUMP_FORWARD L3
L2:
  LOAD_GLOBAL math
  LOAD_ATTR NULL|self + log10
  LOAD_GLOBAL NULL + abs
  LOAD_FAST n
  CALL 1
  CALL 1
  LOAD_CONST 3
  BINARY_OP /
L3:
  CALL 1
  CALL 1
  CALL 2
  CALL 2
  STORE_FAST millidx
  LOAD_CONST '{:.{precision}f}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST n
  LOAD_CONST 10
  LOAD_CONST 3
  LOAD_FAST millidx
  BINARY_OP *
  BINARY_OP **
  BINARY_OP /
  LOAD_FAST precision
  KW_NAMES ('precision',)
  CALL 2
  STORE_FAST result
  LOAD_FAST drop_nulls
  POP_JUMP_IF_FALSE L4
  LOAD_GLOBAL NULL + remove_exponent
  LOAD_GLOBAL NULL + Decimal
  LOAD_FAST result
  CALL 1
  CALL 1
  STORE_FAST result
L4:
  LOAD_CONST '{0}{dx}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST result
  LOAD_FAST millnames
  LOAD_FAST millidx
  BINARY_SUBSCR
  KW_NAMES ('dx',)
  CALL 2
  RETURN_VALUE
END

def millify(n, precision=0, drop_nulls=True, prefixes=[]):
    """pass"""
    millnames = ['', 'k', 'M', 'B', 'T', 'P', 'E', 'Z', 'Y']
    if prefixes:
        millnames = ['']
        millnames.extend(prefixes)
    n = float(n)
    millidx = max(0, min(len(millnames) - 1, int(math.floor(0 if n == 0 else math.log10(abs(n)) / 3))))
    result = '{:.{precision}f}'.format(n / 10 ** (3 * millidx), precision=precision)
    if drop_nulls:
        result = remove_exponent(Decimal(result))
    return '{0}{dx}'.format(result, dx=millnames[millidx])


Input:
CODE <module>()
  DOC ','
  RESUME 0
  LOAD_CONST (',',)
  LOAD_CONST <code prettify>
  MAKE_FUNCTION defaults
  STORE_NAME prettify
  RETURN_CONST None
END
CODE prettify(amount, separator)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + str
  LOAD_FAST amount
  CALL 1
  STORE_FAST orig
  LOAD_GLOBAL re
  LOAD_ATTR NULL|self + sub
  LOAD_CONST '^(-?\\d+)(\\d{3})'
  LOAD_CONST '\\g<1>{0}\\g<2>'
  LOAD_ATTR NULL|self + format
  LOAD_FAST separator
  CALL 1
  LOAD_GLOBAL NULL + str
  LOAD_FAST amount
  CALL 1
  CALL 3
  STORE_FAST new
  LOAD_FAST orig
  LOAD_FAST new
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L1
  LOAD_FAST new
  RETURN_VALUE
L1:
  LOAD_GLOBAL NULL + prettify
  LOAD_FAST new
  CALL 1
  RETURN_VALUE
END

def prettify(amount, separator=','):
    """pass"""
    orig = str(amount)
    new = re.sub('^(-?\\d+)(\\d{3})', '\\g<1>{0}\\g<2>'.format(separator), str(amount))
    if orig == new:
        return new
    else:
        return prettify(new)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (None,)
  LOAD_CONST <code load_json>
  MAKE_FUNCTION defaults
  STORE_NAME load_json
  RETURN_CONST None
END
CODE load_json(json_data, decoder)
  DOC 'pass'
  RESUME 0
  LOAD_FAST decoder
  POP_JUMP_IF_NOT_NONE L1
  LOAD_GLOBAL DateTimeDecoder
  STORE_FAST decoder
L1:
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + loads
  LOAD_FAST json_data
  LOAD_FAST decoder
  LOAD_ATTR decode
  KW_NAMES ('object_hook',)
  CALL 2
  RETURN_VALUE
END

def load_json(json_data, decoder=None):
    """pass"""
    if decoder is None:
        decoder = DateTimeDecoder
    return json.loads(json_data, object_hook=decoder.decode)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (None,)
  LOAD_CONST <code load_json_file>
  MAKE_FUNCTION defaults
  STORE_NAME load_json_file
  RETURN_CONST None
END
CODE load_json_file(file, decoder)
  DOC 'pass'
  RESUME 0
  LOAD_FAST decoder
  POP_JUMP_IF_NOT_NONE L1
  LOAD_GLOBAL DateTimeDecoder
  STORE_FAST decoder
L1:
  LOAD_GLOBAL NULL + hasattr
  LOAD_FAST file
  LOAD_CONST 'read'
  CALL 2
  POP_JUMP_IF_TRUE L4
  LOAD_GLOBAL io
  LOAD_ATTR NULL|self + open
  LOAD_FAST file
  LOAD_CONST 'r'
  LOAD_CONST 'utf-8'
  KW_NAMES ('encoding',)
  CALL 3
  BEFORE_WITH
L2:
  STORE_FAST f
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + load
  LOAD_FAST f
  LOAD_FAST decoder
  LOAD_ATTR decode
  KW_NAMES ('object_hook',)
  CALL 2
L3:
  SWAP 2
  LOAD_CONST None
  LOAD_CONST None
  LOAD_CONST None
  CALL 2
  POP_TOP
  RETURN_VALUE
L4:
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + load
  LOAD_FAST file
  LOAD_FAST decoder
  LOAD_ATTR decode
  KW_NAMES ('object_hook',)
  CALL 2
  RETURN_VALUE
L5:
  PUSH_EXC_INFO
  WITH_EXCEPT_START
  POP_JUMP_IF_TRUE L6
  RERAISE 2
L6:
  POP_TOP
L7:
  POP_EXCEPT
  POP_TOP
  POP_TOP
  JUMP_BACKWARD L4
L8:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L2..L3 -> handler=L5 depth=1 lasti=True
  EXC try=L5..L7 -> handler=L8 depth=3 lasti=True
END

def load_json_file(file, decoder=None):
    """pass"""
    if decoder is None:
        decoder = DateTimeDecoder
    if not hasattr(file, 'read'):
        with io.open(file, 'r', encoding='utf-8') as f:
            return json.load(f, object_hook=decoder.decode)
    return json.load(file, object_hook=decoder.decode)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (False, True, None)
  LOAD_CONST <code save_json>
  MAKE_FUNCTION defaults
  STORE_NAME save_json
  RETURN_CONST None
END
CODE save_json(val, pretty, sort, encoder)
  DOC 'pass'
  RESUME 0
  LOAD_FAST encoder
  POP_JUMP_IF_NOT_NONE L1
  LOAD_GLOBAL DateTimeEncoder
  STORE_FAST encoder
L1:
  LOAD_FAST pretty
  POP_JUMP_IF_FALSE L2
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + dumps
  LOAD_FAST val
  LOAD_CONST 4
  LOAD_CONST (',', ': ')
  LOAD_FAST sort
  LOAD_FAST encoder
  KW_NAMES ('indent', 'separators', 'sort_keys', 'cls')
  CALL 5
  STORE_FAST data
  JUMP_FORWARD L3
L2:
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + dumps
  LOAD_FAST val
  LOAD_CONST (',', ':')
  LOAD_FAST sort
  LOAD_FAST encoder
  KW_NAMES ('separators', 'sort_keys', 'cls')
  CALL 4
  STORE_FAST data
L3:
  LOAD_GLOBAL sys
  LOAD_ATTR version_info
  LOAD_CONST (3, 0)
  COMPARE_OP >
  POP_JUMP_IF_TRUE L4
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST data
  LOAD_GLOBAL str
  CALL 2
  POP_JUMP_IF_FALSE L4
  LOAD_FAST data
  LOAD_ATTR NULL|self + decode
  LOAD_CONST 'utf-8'
  CALL 1
  STORE_FAST data
L4:
  LOAD_FAST data
  RETURN_VALUE
END

def save_json(val, pretty=False, sort=True, encoder=None):
    """pass"""
    if encoder is None:
        encoder = DateTimeEncoder
    if pretty:
        data = json.dumps(val, indent=4, separators=(',', ': '), sort_keys=sort, cls=encoder)
    else:
        data = json.dumps(val, separators=(',', ':'), sort_keys=sort, cls=encoder)
    if not sys.version_info > (3, 0) and isinstance(data, str):
        data = data.decode('utf-8')
    return data


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (False, True, True, None)
  LOAD_CONST <code save_json_file>
  MAKE_FUNCTION defaults
  STORE_NAME save_json_file
  RETURN_CONST None
END
CODE save_json_file(file, val, pretty, compact, sort, encoder)
  DOC 'pass'
  RESUME 0
  LOAD_FAST encoder
  POP_JUMP_IF_NOT_NONE L1
  LOAD_GLOBAL DateTimeEncoder
  STORE_FAST encoder
L1:
  LOAD_CONST False
  STORE_FAST opened
  LOAD_GLOBAL NULL + hasattr
  LOAD_FAST file
  LOAD_CONST 'write'
  CALL 2
  POP_JUMP_IF_TRUE L2
  LOAD_GLOBAL io
  LOAD_ATTR NULL|self + open
  LOAD_FAST file
  LOAD_CONST 'w'
  LOAD_CONST 'utf-8'
  KW_NAMES ('encoding',)
  CALL 3
  STORE_FAST file
  LOAD_CONST True
  STORE_FAST opened
L2:
  NOP
L3:
  LOAD_FAST pretty
  POP_JUMP_IF_FALSE L4
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + dumps
  LOAD_FAST val
  LOAD_CONST 4
  LOAD_CONST (',', ': ')
  LOAD_FAST sort
  LOAD_FAST encoder
  KW_NAMES ('indent', 'separators', 'sort_keys', 'cls')
  CALL 5
  STORE_FAST data
  JUMP_FORWARD L6
L4:
  LOAD_FAST compact
  POP_JUMP_IF_FALSE L5
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + dumps
  LOAD_FAST val
  LOAD_CONST (',', ':')
  LOAD_FAST sort
  LOAD_FAST encoder
  KW_NAMES ('separators', 'sort_keys', 'cls')
  CALL 4
  STORE_FAST data
  JUMP_FORWARD L6
L5:
  LOAD_GLOBAL json
  LOAD_ATTR NULL|self + dumps
  LOAD_FAST val
  LOAD_FAST sort
  LOAD_FAST encoder
  KW_NAMES ('sort_keys', 'cls')
  CALL 3
  STORE_FAST data
L6:
  LOAD_GLOBAL sys
  LOAD_ATTR version_info
  LOAD_CONST (3, 0)
  COMPARE_OP >
  POP_JUMP_IF_TRUE L7
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST data
  LOAD_GLOBAL str
  CALL 2
  POP_JUMP_IF_FALSE L7
  LOAD_FAST data
  LOAD_ATTR NULL|self + decode
  LOAD_CONST 'utf-8'
  CALL 1
  STORE_FAST data
L7:
  LOAD_FAST file
  LOAD_ATTR NULL|self + write
  LOAD_FAST data
  CALL 1
  POP_TOP
L8:
  LOAD_FAST opened
  POP_JUMP_IF_FALSE L9
  LOAD_FAST file
  LOAD_ATTR NULL|self + close
  CALL 0
  POP_TOP
  RETURN_CONST None
L9:
  RETURN_CONST None
L10:
  PUSH_EXC_INFO
  LOAD_FAST opened
  POP_JUMP_IF_FALSE L11
  LOAD_FAST file
  LOAD_ATTR NULL|self + close
  CALL 0
  POP_TOP
  RERAISE 0
L11:
  RERAISE 0
L12:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L3..L8 -> handler=L10 depth=0 lasti=False
  EXC try=L10..L12 -> handler=L12 depth=1 lasti=True
END

def save_json_file(file, val, pretty=False, compact=True, sort=True, encoder=None):
    """pass"""
    if encoder is None:
        encoder = DateTimeEncoder
    opened = False
    if not hasattr(file, 'write'):
        file = io.open(file, 'w', encoding='utf-8')
        opened = True
    try:
        if pretty:
            data = json.dumps(val, indent=4, separators=(',', ': '), sort_keys=sort, cls=encoder)
        elif compact:
            data = json.dumps(val, separators=(',', ':'), sort_keys=sort, cls=encoder)
        else:
            data = json.dumps(val, sort_keys=sort, cls=encoder)
        if not sys.version_info > (3, 0) and isinstance(data, str):
            data = data.decode('utf-8')
        file.write(data)
    finally:
        if opened:
            file.close()


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code load_yaml_file>
  MAKE_FUNCTION 0
  STORE_NAME load_yaml_file
  RETURN_CONST None
END
CODE load_yaml_file(file)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + hasattr
  LOAD_FAST file
  LOAD_CONST 'read'
  CALL 2
  POP_JUMP_IF_TRUE L3
  LOAD_GLOBAL io
  LOAD_ATTR NULL|self + open
  LOAD_FAST file
  LOAD_CONST 'r'
  LOAD_CONST 'utf-8'
  KW_NAMES ('encoding',)
  CALL 3
  BEFORE_WITH
L1:
  STORE_FAST f
  LOAD_GLOBAL yaml
  LOAD_ATTR NULL|self + load
  LOAD_FAST f
  LOAD_GLOBAL yaml
  LOAD_ATTR FullLoader
  CALL 2
L2:
  SWAP 2
  LOAD_CONST None
  LOAD_CONST None
  LOAD_CONST None
  CALL 2
  POP_TOP
  RETURN_VALUE
L3:
  LOAD_GLOBAL yaml
  LOAD_ATTR NULL|self + load
  LOAD_FAST file
  LOAD_GLOBAL yaml
  LOAD_ATTR FullLoader
  CALL 2
  RETURN_VALUE
L4:
  PUSH_EXC_INFO
  WITH_EXCEPT_START
  POP_JUMP_IF_TRUE L5
  RERAISE 2
L5:
  POP_TOP
L6:
  POP_EXCEPT
  POP_TOP
  POP_TOP
  JUMP_BACKWARD L3
L7:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L1..L2 -> handler=L4 depth=1 lasti=True
  EXC try=L4..L6 -> handler=L7 depth=3 lasti=True
END

def load_yaml_file(file):
    """pass"""
    if not hasattr(file, 'read'):
        with io.open(file, 'r', encoding='utf-8') as f:
            return yaml.load(f, yaml.FullLoader)
    return yaml.load(file, yaml.FullLoader)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code save_yaml_file>
  MAKE_FUNCTION 0
  STORE_NAME save_yaml_file
  RETURN_CONST None
END
CODE save_yaml_file(file, val)
  DOC 'pass'
  RESUME 0
  LOAD_CONST False
  STORE_FAST opened
  LOAD_GLOBAL NULL + hasattr
  LOAD_FAST file
  LOAD_CONST 'write'
  CALL 2
  POP_JUMP_IF_TRUE L1
  LOAD_GLOBAL io
  LOAD_ATTR NULL|self + open
  LOAD_FAST file
  LOAD_CONST 'w'
  LOAD_CONST 'utf-8'
  KW_NAMES ('encoding',)
  CALL 3
  STORE_FAST file
  LOAD_CONST True
  STORE_FAST opened
L1:
  NOP
L2:
  LOAD_GLOBAL yaml
  LOAD_ATTR NULL|self + dump
  LOAD_FAST val
  LOAD_FAST file
  CALL 2
  POP_TOP
L3:
  LOAD_FAST opened
  POP_JUMP_IF_FALSE L4
  LOAD_FAST file
  LOAD_ATTR NULL|self + close
  CALL 0
  POP_TOP
  RETURN_CONST None
L4:
  RETURN_CONST None
L5:
  PUSH_EXC_INFO
  LOAD_FAST opened
  POP_JUMP_IF_FALSE L6
  LOAD_FAST file
  LOAD_ATTR NULL|self + close
  CALL 0
  POP_TOP
  RERAISE 0
L6:
  RERAISE 0
L7:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L2..L3 -> handler=L5 depth=0 lasti=False
  EXC try=L5..L7 -> handler=L7 depth=1 lasti=True
END

def save_yaml_file(file, val):
    """pass"""
    opened = False
    if not hasattr(file, 'write'):
        file = io.open(file, 'w', encoding='utf-8')
        opened = True
    try:
        yaml.dump(val, file)
    finally:
        if opened:
            file.close()


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code get_embedded_yara>
  MAKE_FUNCTION 0
  STORE_NAME get_embedded_yara
  RETURN_CONST None
END
CODE get_embedded_yara(self, iocid)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR iocs
  LOAD_FAST iocid
  BINARY_SUBSCR
  STORE_FAST ioc_obj
  LOAD_GLOBAL NULL + set
  BUILD_LIST 0
  CALL 1
  STORE_FAST ids_to_process
  LOAD_CONST ''
  STORE_FAST signatures
  LOAD_FAST ioc_obj
  LOAD_ATTR top_level_indicator
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST './/IndicatorItem[Context/@search = "Yara/Yara"]'
  CALL 1
  GET_ITER
L1:
  FOR_ITER L2
  STORE_FAST elem
  LOAD_FAST elem
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'Content'
  CALL 1
  STORE_FAST signature
  LOAD_FAST signatures
  LOAD_CONST '\n'
  BINARY_OP +
  LOAD_FAST signature
  BINARY_OP +
  STORE_FAST signatures
  JUMP_BACKWARD L1
L2:
  END_FOR
  LOAD_FAST signatures
  POP_JUMP_IF_FALSE L3
  LOAD_FAST signatures
  LOAD_CONST '\n'
  BINARY_OP +=
  STORE_FAST signatures
L3:
  LOAD_FAST signatures
  RETURN_VALUE
END

def get_embedded_yara(self, iocid):
    """pass"""
    ioc_obj = self.iocs[iocid]
    ids_to_process = set([])
    signatures = ''
    for elem in ioc_obj.top_level_indicator.xpath('.//IndicatorItem[Context/@search = "Yara/Yara"]'):
        signature = elem.findtext('Content')
        signatures = signatures + '\n' + signature
    if signatures:
        signatures += '\n'
    return signatures


Input:
CODE <module>()
  DOC ''
  RESUME 0
  LOAD_CONST ('', 'or')
  LOAD_CONST <code get_yara_condition_string>
  MAKE_FUNCTION defaults
  STORE_NAME get_yara_condition_string
  RETURN_CONST None
END
CODE get_yara_condition_string(self, indicator_node, parameters_node, ids_to_process, condition_string, joining_value)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + str
  LOAD_FAST indicator_node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'id'
  CALL 1
  CALL 1
  STORE_FAST indicator_node_id
  LOAD_FAST indicator_node_id
  LOAD_FAST ids_to_process
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L1
  LOAD_CONST 'Entered into get_yara_condition_string with a invalid node to walk [[}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST indicator_node_id
  CALL 1
  STORE_FAST msg
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_FAST msg
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_CONST 'Indicator'
  STORE_FAST expected_tag
  LOAD_FAST indicator_node
  LOAD_ATTR tag
  LOAD_FAST expected_tag
  COMPARE_OP !=
  POP_JUMP_IF_FALSE L2
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'indicator_node expected tag is [%s]'
  LOAD_FAST expected_tag
  BINARY_OP %
  CALL 1
  RAISE_VARARGS 1
L2:
  LOAD_CONST None
  STORE_FAST is_set
  LOAD_FAST parameters_node
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST './/param[@ref-id="{}"]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST indicator_node_id
  CALL 1
  CALL 1
  GET_ITER
L3:
  FOR_ITER L8
  STORE_FAST param
  LOAD_FAST param
  LOAD_ATTR attrib
  LOAD_CONST 'name'
  BINARY_SUBSCR
  LOAD_CONST 'yara/set'
  COMPARE_OP ==
  POP_JUMP_IF_TRUE L4
  JUMP_BACKWARD L3
L4:
  LOAD_CONST True
  STORE_FAST is_set
  LOAD_FAST param
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'value'
  LOAD_CONST None
  CALL 2
  STORE_FAST set_count
  NOP
L5:
  LOAD_GLOBAL NULL + int
  LOAD_FAST set_count
  CALL 1
  STORE_FAST temp
  LOAD_FAST temp
  LOAD_CONST 1
  COMPARE_OP <
  POP_JUMP_IF_FALSE L6
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'yara/set parameter value was less than 1'
  CALL 1
  RAISE_VARARGS 1
L6:
  LOAD_FAST temp
  LOAD_GLOBAL NULL + len
  LOAD_FAST indicator_node
  LOAD_ATTR NULL|self + getchildren
  CALL 0
  CALL 1
  COMPARE_OP >
  POP_JUMP_IF_FALSE L7
  LOAD_CONST 'yara/set value is greater than the number of children of Indicator node [%s]'
  LOAD_GLOBAL NULL + str
  LOAD_FAST indicator_node_id
  CALL 1
  BINARY_OP %
  STORE_FAST msg
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_FAST msg
  CALL 1
  RAISE_VARARGS 1
L7:
  NOP
  LOAD_FAST set_count
  BUILD_LIST 0
  LOAD_CONST ('set_count', 'set_ids')
  BUILD_CONST_KEY_MAP 2
  STORE_FAST set_dict
  JUMP_BACKWARD L3
L8:
  END_FOR
  LOAD_FAST indicator_node
  LOAD_ATTR NULL|self + getchildren
  CALL 0
  GET_ITER
L9:
  EXTENDED_ARG 4
  FOR_ITER L36
  STORE_FAST node
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'id'
  CALL 1
  STORE_FAST node_id
  LOAD_FAST node_id
  LOAD_ATTR NULL|self + replace
  LOAD_CONST '-'
  LOAD_CONST ''
  CALL 2
  STORE_FAST safe_node_id
  LOAD_FAST node_id
  LOAD_FAST ids_to_process
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L10
  JUMP_BACKWARD L9
L10:
  LOAD_FAST node
  LOAD_ATTR tag
  LOAD_CONST 'IndicatorItem'
  COMPARE_OP ==
  EXTENDED_ARG 3
  POP_JUMP_IF_FALSE L30
  LOAD_FAST is_set
  POP_JUMP_IF_FALSE L11
  LOAD_FAST_CHECK set_dict
  LOAD_CONST 'set_ids'
  BINARY_SUBSCR
  LOAD_ATTR NULL|self + append
  LOAD_CONST '$'
  LOAD_FAST safe_node_id
  BINARY_OP +
  CALL 1
  POP_TOP
  JUMP_BACKWARD L9
L11:
  LOAD_CONST '$'
  LOAD_FAST safe_node_id
  LOAD_CONST ''
  LOAD_CONST ''
  LOAD_CONST ('prefix', 'identifier', 'condition', 'postfix')
  BUILD_CONST_KEY_MAP 4
  STORE_FAST mapping
  LOAD_CONST False
  STORE_FAST use_condition_template
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'negate'
  CALL 1
  STORE_FAST negation
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'condition'
  CALL 1
  STORE_FAST condition
  LOAD_FAST node
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST 'Context/@search'
  CALL 1
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST search
  LOAD_FAST node
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'Content'
  CALL 1
  STORE_FAST content
  LOAD_FAST self
  LOAD_ATTR condition_to_yara_map
  LOAD_FAST condition
  BINARY_SUBSCR
  STORE_FAST yara_condition
  LOAD_FAST yara_condition
  POP_JUMP_IF_TRUE L12
  LOAD_CONST 'Invalid IndicatorItem condition encountered ['
  LOAD_GLOBAL NULL + str
  LOAD_FAST node_id
  CALL 1
  FORMAT_VALUE str
  LOAD_CONST ']['
  LOAD_GLOBAL NULL + str
  LOAD_FAST condition
  CALL 1
  FORMAT_VALUE str
  LOAD_CONST ']'
  BUILD_STRING 5
  STORE_FAST msg
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_FAST msg
  CALL 1
  RAISE_VARARGS 1
L12:
  LOAD_FAST negation
  LOAD_ATTR NULL|self + lower
  CALL 0
  LOAD_CONST 'true'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L13
  LOAD_CONST True
  STORE_FAST negation
  JUMP_FORWARD L14
L13:
  LOAD_CONST False
  STORE_FAST negation
L14:
  LOAD_FAST search
  LOAD_CONST 'Yara/FileSize'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L15
  LOAD_CONST ''
  LOAD_FAST mapping
  LOAD_CONST 'prefix'
  STORE_SUBSCR
  LOAD_CONST 'filesize'
  LOAD_FAST mapping
  LOAD_CONST 'identifier'
  STORE_SUBSCR
  LOAD_CONST ' '
  LOAD_FAST content
  BINARY_OP +
  LOAD_FAST mapping
  LOAD_CONST 'postfix'
  STORE_SUBSCR
  LOAD_FAST yara_condition
  LOAD_FAST mapping
  LOAD_CONST 'condition'
  STORE_SUBSCR
  LOAD_CONST True
  STORE_FAST use_condition_template
  EXTENDED_ARG 2
  JUMP_FORWARD L26
L15:
  LOAD_FAST search
  LOAD_CONST 'Yara/RuleName'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L19
  LOAD_FAST content
  LOAD_FAST self
  LOAD_ATTR ioc_names_set
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L17
  LOAD_GLOBAL NULL + mangle_name
  LOAD_FAST content
  CALL 1
  LOAD_FAST self
  LOAD_ATTR ioc_names_mangled_set
  CONTAINS_OP 0
  POP_JUMP_IF_FALSE L16
  LOAD_CONST 'Yara/RuleName is present as a mangled name.[{}][{}]'
  LOAD_ATTR NULL|self + format
  LOAD_GLOBAL NULL + mangle_name
  LOAD_FAST content
  CALL 1
  LOAD_FAST node_id
  CALL 2
  STORE_FAST msg
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + warning
  LOAD_FAST msg
  CALL 1
  POP_TOP
  LOAD_GLOBAL NULL + mangle_name
  LOAD_FAST content
  CALL 1
  STORE_FAST content
  JUMP_FORWARD L17
L16:
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + warning
  LOAD_CONST 'Yara/RuleName points to a name [{}] that is not in the set of IOCs being processed [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST content
  LOAD_FAST node_id
  CALL 2
  CALL 1
  POP_TOP
L17:
  LOAD_GLOBAL NULL + mangle_name
  LOAD_FAST content
  CALL 1
  LOAD_FAST content
  COMPARE_OP !=
  POP_JUMP_IF_FALSE L18
  LOAD_CONST 'Yara/RuleName contains characters which would cause libyara errors [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST node_id
  CALL 1
  STORE_FAST msg
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_FAST msg
  CALL 1
  RAISE_VARARGS 1
L18:
  LOAD_CONST ''
  LOAD_FAST mapping
  LOAD_CONST 'prefix'
  STORE_SUBSCR
  LOAD_FAST content
  LOAD_FAST mapping
  LOAD_CONST 'identifier'
  STORE_SUBSCR
  EXTENDED_ARG 1
  JUMP_FORWARD L26
L19:
  LOAD_CONST './/param[@ref-id="{}" and (@name="yara/count" or @name="yara/offset/at" or @name="yara/offset/in")]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST node_id
  CALL 1
  STORE_FAST xp
  LOAD_FAST parameters_node
  LOAD_ATTR NULL|self + xpath
  LOAD_FAST xp
  CALL 1
  STORE_FAST params
  LOAD_GLOBAL NULL + len
  LOAD_FAST params
  CALL 1
  LOAD_CONST 1
  COMPARE_OP >
  POP_JUMP_IF_FALSE L20
  LOAD_CONST 'More than one condition parameters assigned to IndicatorItem [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST node_id
  CALL 1
  STORE_FAST msg
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_FAST msg
  CALL 1
  RAISE_VARARGS 1
L20:
  LOAD_FAST params
  GET_ITER
L21:
  EXTENDED_ARG 1
  FOR_ITER L25
  STORE_FAST param
  LOAD_FAST param
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'name'
  LOAD_CONST None
  CALL 2
  STORE_FAST param_name
  LOAD_FAST param_name
  LOAD_CONST 'yara/count'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L22
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + debug
  LOAD_CONST 'Found ['
  LOAD_FAST param
  LOAD_ATTR attrib
  LOAD_CONST 'name'
  BINARY_SUBSCR
  FORMAT_VALUE str
  LOAD_CONST '] attached to ['
  LOAD_FAST node_id
  FORMAT_VALUE str
  LOAD_CONST ']'
  BUILD_STRING 5
  CALL 1
  POP_TOP
  LOAD_CONST '#'
  LOAD_FAST mapping
  LOAD_CONST 'prefix'
  STORE_SUBSCR
  LOAD_CONST ' '
  LOAD_FAST param
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'value'
  CALL 1
  BINARY_OP +
  LOAD_FAST mapping
  LOAD_CONST 'postfix'
  STORE_SUBSCR
  LOAD_FAST yara_condition
  LOAD_FAST mapping
  LOAD_CONST 'condition'
  STORE_SUBSCR
  LOAD_CONST True
  STORE_FAST use_condition_template
  POP_TOP
  JUMP_FORWARD L26
L22:
  LOAD_FAST param_name
  LOAD_CONST 'yara/offset/at'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L23
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + debug
  LOAD_CONST 'Found ['
  LOAD_FAST param
  LOAD_ATTR attrib
  LOAD_CONST 'name'
  BINARY_SUBSCR
  FORMAT_VALUE str
  LOAD_CONST '] attached to ['
  LOAD_FAST node_id
  FORMAT_VALUE str
  LOAD_CONST ']'
  BUILD_STRING 5
  CALL 1
  POP_TOP
  LOAD_CONST 'at'
  LOAD_FAST mapping
  LOAD_CONST 'condition'
  STORE_SUBSCR
  LOAD_CONST ' '
  LOAD_FAST param
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'value'
  CALL 1
  BINARY_OP +
  LOAD_FAST mapping
  LOAD_CONST 'postfix'
  STORE_SUBSCR
  LOAD_CONST True
  STORE_FAST use_condition_template
  POP_TOP
  JUMP_FORWARD L26
L23:
  LOAD_FAST param_name
  LOAD_CONST 'yara/offset/in'
  COMPARE_OP ==
  POP_JUMP_IF_TRUE L24
  JUMP_BACKWARD L21
L24:
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + debug
  LOAD_CONST 'Found ['
  LOAD_FAST param
  LOAD_ATTR attrib
  LOAD_CONST 'name'
  BINARY_SUBSCR
  FORMAT_VALUE str
  LOAD_CONST '] attached to ['
  LOAD_FAST node_id
  FORMAT_VALUE str
  LOAD_CONST ']'
  BUILD_STRING 5
  CALL 1
  POP_TOP
  LOAD_CONST 'in'
  LOAD_FAST mapping
  LOAD_CONST 'condition'
  STORE_SUBSCR
  LOAD_CONST ' '
  LOAD_FAST param
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'value'
  CALL 1
  BINARY_OP +
  LOAD_FAST mapping
  LOAD_CONST 'postfix'
  STORE_SUBSCR
  LOAD_CONST True
  STORE_FAST use_condition_template
  POP_TOP
  JUMP_FORWARD L26
L25:
  END_FOR
L26:
  LOAD_FAST use_condition_template
  POP_JUMP_IF_FALSE L27
  LOAD_FAST self
  LOAD_ATTR yara_II_condition_template
  LOAD_FAST mapping
  BINARY_OP %
  STORE_FAST temp_string
  JUMP_FORWARD L28
L27:
  LOAD_FAST self
  LOAD_ATTR yara_II_template
  LOAD_FAST mapping
  BINARY_OP %
  STORE_FAST temp_string
L28:
  LOAD_FAST condition_string
  LOAD_CONST ''
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L29
  LOAD_FAST temp_string
  STORE_FAST condition_string
  EXTENDED_ARG 3
  JUMP_BACKWARD L9
L29:
  LOAD_CONST ' '
  LOAD_ATTR NULL|self + join
  LOAD_FAST condition_string
  LOAD_FAST joining_value
  LOAD_FAST temp_string
  BUILD_LIST 3
  CALL 1
  STORE_FAST condition_string
  EXTENDED_ARG 3
  JUMP_BACKWARD L9
L30:
  LOAD_FAST node
  LOAD_ATTR tag
  LOAD_CONST 'Indicator'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L35
  LOAD_FAST is_set
  POP_JUMP_IF_FALSE L31
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'Cannot have Indicator nodes underneath a Indicator node with yara/set'
  CALL 1
  RAISE_VARARGS 1
L31:
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'operator'
  CALL 1
  LOAD_ATTR NULL|self + lower
  CALL 0
  STORE_FAST operator
  LOAD_FAST operator
  LOAD_CONST ('or', 'and')
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L32
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'Indicator@operator is not and/or. ['
  LOAD_GLOBAL id
  FORMAT_VALUE str
  LOAD_CONST '] has ['
  LOAD_FAST operator
  FORMAT_VALUE str
  LOAD_CONST ']'
  BUILD_STRING 5
  CALL 1
  RAISE_VARARGS 1
L32:
  LOAD_FAST self
  LOAD_ATTR NULL|self + get_yara_condition_string
  LOAD_FAST node
  LOAD_FAST parameters_node
  LOAD_FAST ids_to_process
  LOAD_CONST ''
  LOAD_FAST operator
  CALL 5
  STORE_FAST recursed_condition
  LOAD_CONST './/param[@ref-id="{}" and @name="yara/set"]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST node_id
  CALL 1
  STORE_FAST xp
  LOAD_FAST parameters_node
  LOAD_ATTR NULL|self + xpath
  LOAD_FAST xp
  CALL 1
  POP_JUMP_IF_TRUE L33
  LOAD_GLOBAL NULL + has_siblings
  LOAD_FAST node
  CALL 1
  POP_JUMP_IF_FALSE L33
  LOAD_CONST '(%s)'
  LOAD_FAST recursed_condition
  BINARY_OP %
  STORE_FAST recursed_condition
L33:
  LOAD_FAST condition_string
  LOAD_CONST ''
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L34
  LOAD_FAST recursed_condition
  STORE_FAST condition_string
  EXTENDED_ARG 4
  JUMP_BACKWARD L9
L34:
  LOAD_CONST ' '
  LOAD_ATTR NULL|self + join
  LOAD_FAST condition_string
  LOAD_FAST joining_value
  LOAD_FAST recursed_condition
  BUILD_LIST 3
  CALL 1
  STORE_FAST condition_string
  EXTENDED_ARG 4
  JUMP_BACKWARD L9
L35:
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'node.tag is not a Indicator/IndicatorItem [%s]'
  LOAD_GLOBAL NULL + str
  LOAD_GLOBAL id
  CALL 1
  BINARY_OP %
  CALL 1
  RAISE_VARARGS 1
L36:
  END_FOR
  LOAD_FAST is_set
  POP_JUMP_IF_FALSE L41
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + debug
  LOAD_CONST 'Building set expression for [%s]'
  LOAD_FAST indicator_node_id
  BINARY_OP %
  CALL 1
  POP_TOP
  LOAD_GLOBAL NULL + len
  LOAD_FAST_CHECK set_dict
  LOAD_CONST 'set_ids'
  BINARY_SUBSCR
  CALL 1
  LOAD_CONST 0
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L37
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'yara/set processing did not yield any set ids'
  CALL 1
  RAISE_VARARGS 1
L37:
  LOAD_GLOBAL NULL + len
  LOAD_FAST set_dict
  LOAD_CONST 'set_ids'
  BINARY_SUBSCR
  CALL 1
  LOAD_CONST 1
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L38
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + warning
  LOAD_CONST 'yara/set with 1 id found for node [%s]'
  LOAD_FAST_CHECK node_id
  BINARY_OP %
  CALL 1
  POP_TOP
  LOAD_CONST ''
  LOAD_ATTR NULL|self + join
  LOAD_FAST set_dict
  LOAD_CONST 'set_ids'
  BINARY_SUBSCR
  CALL 1
  STORE_FAST set_ids
  JUMP_FORWARD L39
L38:
  LOAD_CONST ','
  LOAD_ATTR NULL|self + join
  LOAD_FAST set_dict
  LOAD_CONST 'set_ids'
  BINARY_SUBSCR
  CALL 1
  STORE_FAST set_ids
L39:
  LOAD_FAST set_ids
  LOAD_FAST set_dict
  LOAD_CONST 'set_ids'
  STORE_SUBSCR
  LOAD_FAST self
  LOAD_ATTR yara_set_string_template
  LOAD_FAST set_dict
  BINARY_OP %
  STORE_FAST temp_set_string
  LOAD_FAST condition_string
  LOAD_CONST ''
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L40
  LOAD_FAST temp_set_string
  STORE_FAST condition_string
  LOAD_FAST condition_string
  RETURN_VALUE
L40:
  LOAD_CONST ' '
  LOAD_ATTR NULL|self + join
  LOAD_FAST condition_string
  LOAD_FAST indicator_node
  LOAD_ATTR NULL|self + getparent
  CALL 0
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'operator'
  CALL 1
  LOAD_ATTR NULL|self + lower
  CALL 0
  LOAD_FAST temp_set_string
  BUILD_LIST 3
  CALL 1
  STORE_FAST condition_string
L41:
  LOAD_FAST condition_string
  RETURN_VALUE
L42:
  PUSH_EXC_INFO
  LOAD_GLOBAL ValueError
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L43
  POP_TOP
  LOAD_GLOBAL NULL + YaraConversionError
  LOAD_CONST 'yara/set parameter was not a integer'
  CALL 1
  RAISE_VARARGS 1
L43:
  RERAISE 0
L44:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L5..L7 -> handler=L42 depth=1 lasti=False
  EXC try=L42..L44 -> handler=L44 depth=2 lasti=True
END

def get_yara_condition_string(self, indicator_node, parameters_node, ids_to_process, condition_string='', joining_value='or'):
    """pass"""
    indicator_node_id = str(indicator_node.get('id'))
    if indicator_node_id not in ids_to_process:
        msg = 'Entered into get_yara_condition_string with a invalid node to walk [[}]'.format(indicator_node_id)
        raise YaraConversionError(msg)
    expected_tag = 'Indicator'
    if indicator_node.tag != expected_tag:
        raise YaraConversionError('indicator_node expected tag is [%s]' % expected_tag)
    is_set = None
    for param in parameters_node.xpath('.//param[@ref-id="{}"]'.format(indicator_node_id)):
        if param.attrib['name'] == 'yara/set':
            is_set = True
            set_count = param.findtext('value', None)
            try:
                temp = int(set_count)
                if temp < 1:
                    raise YaraConversionError('yara/set parameter value was less than 1')
                if temp > len(indicator_node.getchildren()):
                    msg = 'yara/set value is greater than the number of children of Indicator node [%s]' % str(indicator_node_id)
                    raise YaraConversionError(msg)
            except ValueError:
                raise YaraConversionError('yara/set parameter was not a integer')
            set_dict = {'set_count': set_count, 'set_ids': []}
    for node in indicator_node.getchildren():
        node_id = node.get('id')
        safe_node_id = node_id.replace('-', '')
        if node_id not in ids_to_process:
            continue
        if node.tag == 'IndicatorItem':
            if is_set:
                set_dict['set_ids'].append('$' + safe_node_id)
            else:
                mapping = {'prefix': '$', 'identifier': safe_node_id, 'condition': '', 'postfix': ''}
                use_condition_template = False
                negation = node.get('negate')
                condition = node.get('condition')
                search = node.xpath('Context/@search')[0]
                content = node.findtext('Content')
                yara_condition = self.condition_to_yara_map[condition]
                if not yara_condition:
                    msg = 'Invalid IndicatorItem condition encountered [%s][%s]' % (str(node_id), str(condition))
                    raise YaraConversionError(msg)
                if negation.lower() == 'true':
                    negation = True
                else:
                    negation = False
                if search == 'Yara/FileSize':
                    mapping['prefix'] = ''
                    mapping['identifier'] = 'filesize'
                    mapping['postfix'] = ' ' + content
                    mapping['condition'] = yara_condition
                    use_condition_template = True
                elif search == 'Yara/RuleName':
                    if content not in self.ioc_names_set:
                        if mangle_name(content) in self.ioc_names_mangled_set:
                            msg = 'Yara/RuleName is present as a mangled name.[{}][{}]'.format(mangle_name(content), node_id)
                            log.warning(msg)
                            content = mangle_name(content)
                        else:
                            log.warning('Yara/RuleName points to a name [{}] that is not in the set of IOCs being processed [{}]'.format(content, node_id))
                    if mangle_name(content) != content:
                        msg = 'Yara/RuleName contains characters which would cause libyara errors [{}]'.format(node_id)
                        raise YaraConversionError(msg)
                    mapping['prefix'] = ''
                    mapping['identifier'] = content
                else:
                    xp = './/param[@ref-id="{}" and (@name="yara/count" or @name="yara/offset/at" or @name="yara/offset/in")]'.format(node_id)
                    params = parameters_node.xpath(xp)
                    if len(params) > 1:
                        msg = 'More than one condition parameters assigned to IndicatorItem [{}]'.format(node_id)
                        raise YaraConversionError(msg)
                    for param in params:
                        param_name = param.get('name', None)
                        if param_name == 'yara/count':
                            log.debug('Found [%s] attached to [%s]' % (param.attrib['name'], node_id))
                            mapping['prefix'] = '#'
                            mapping['postfix'] = ' ' + param.findtext('value')
                            mapping['condition'] = yara_condition
                            use_condition_template = True
                            break
                        elif param_name == 'yara/offset/at':
                            log.debug('Found [%s] attached to [%s]' % (param.attrib['name'], node_id))
                            mapping['condition'] = 'at'
                            mapping['postfix'] = ' ' + param.findtext('value')
                            use_condition_template = True
                            break
                        elif param_name == 'yara/offset/in':
                            log.debug('Found [%s] attached to [%s]' % (param.attrib['name'], node_id))
                            mapping['condition'] = 'in'
                            mapping['postfix'] = ' ' + param.findtext('value')
                            use_condition_template = True
                            break
                if use_condition_template:
                    temp_string = self.yara_II_condition_template % mapping
                else:
                    temp_string = self.yara_II_template % mapping
                if condition_string == '':
                    condition_string = temp_string
                else:
                    condition_string = ' '.join([condition_string, joining_value, temp_string])
        elif node.tag == 'Indicator':
            if is_set:
                raise YaraConversionError('Cannot have Indicator nodes underneath a Indicator node with yara/set')
            operator = node.get('operator').lower()
            if operator not in ['or', 'and']:
                raise YaraConversionError('Indicator@operator is not and/or. [%s] has [%s]' % (id, operator))
            recursed_condition = self.get_yara_condition_string(node, parameters_node, ids_to_process, '', operator)
            xp = './/param[@ref-id="{}" and @name="yara/set"]'.format(node_id)
            if not parameters_node.xpath(xp) and has_siblings(node):
                recursed_condition = '(%s)' % recursed_condition
            if condition_string == '':
                condition_string = recursed_condition
            else:
                condition_string = ' '.join([condition_string, joining_value, recursed_condition])
        else:
            raise YaraConversionError('node.tag is not a Indicator/IndicatorItem [%s]' % str(id))
    if is_set:
        log.debug('Building set expression for [%s]' % indicator_node_id)
        if len(set_dict['set_ids']) == 0:
            raise YaraConversionError('yara/set processing did not yield any set ids')
        elif len(set_dict['set_ids']) == 1:
            log.warning('yara/set with 1 id found for node [%s]' % node_id)
            set_ids = ''.join(set_dict['set_ids'])
        else:
            set_ids = ','.join(set_dict['set_ids'])
        set_dict['set_ids'] = set_ids
        temp_set_string = self.yara_set_string_template % set_dict
        if condition_string == '':
            condition_string = temp_set_string
        else:
            condition_string = ' '.join([condition_string, indicator_node.getparent().get('operator').lower(), temp_set_string])
    return condition_string


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code write_yara>
  MAKE_FUNCTION 0
  STORE_NAME write_yara
  RETURN_CONST None
END
CODE write_yara(self, output_file)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + open
  LOAD_FAST output_file
  LOAD_CONST 'wb'
  CALL 2
  STORE_FAST fout
  LOAD_FAST fout
  LOAD_ATTR NULL|self + write
  LOAD_CONST '\n'
  CALL 1
  POP_TOP
  LOAD_FAST self
  LOAD_ATTR yara_signatures
  GET_ITER
L1:
  FOR_ITER L2
  STORE_FAST iocid
  LOAD_FAST self
  LOAD_ATTR yara_signatures
  LOAD_FAST iocid
  BINARY_SUBSCR
  STORE_FAST signature
  LOAD_FAST fout
  LOAD_ATTR NULL|self + write
  LOAD_FAST signature
  CALL 1
  POP_TOP
  LOAD_FAST fout
  LOAD_ATTR NULL|self + write
  LOAD_CONST '\n'
  CALL 1
  POP_TOP
  JUMP_BACKWARD L1
L2:
  END_FOR
  LOAD_FAST fout
  LOAD_ATTR NULL|self + close
  CALL 0
  POP_TOP
  RETURN_CONST True
END

def write_yara(self, output_file):
    """pass"""
    fout = open(output_file, 'wb')
    fout.write('\n')
    for iocid in self.yara_signatures:
        signature = self.yara_signatures[iocid]
        fout.write(signature)
        fout.write('\n')
    fout.close()
    return True


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code safe_makedirs>
  MAKE_FUNCTION 0
  STORE_NAME safe_makedirs
  RETURN_CONST None
END
CODE safe_makedirs(fdir)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL os
  LOAD_ATTR path
  LOAD_ATTR NULL|self + isdir
  LOAD_FAST fdir
  CALL 1
  POP_JUMP_IF_FALSE L1
  NOP
  RETURN_CONST True
L1:
  NOP
L2:
  LOAD_GLOBAL os
  LOAD_ATTR NULL|self + makedirs
  LOAD_FAST fdir
  CALL 1
  POP_TOP
L3:
  RETURN_CONST True
L4:
  PUSH_EXC_INFO
  LOAD_GLOBAL WindowsError
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L9
  STORE_FAST e
L5:
  LOAD_CONST 'Cannot create a file when that file already exists'
  LOAD_FAST e
  CONTAINS_OP 0
  POP_JUMP_IF_FALSE L6
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + debug
  LOAD_CONST 'relevant dir already exists'
  CALL 1
  POP_TOP
  JUMP_FORWARD L7
L6:
  LOAD_GLOBAL NULL + WindowsError
  LOAD_FAST e
  CALL 1
  RAISE_VARARGS 1
L7:
  POP_EXCEPT
  LOAD_CONST None
  STORE_FAST e
  DELETE_FAST e
  RETURN_CONST True
L8:
  LOAD_CONST None
  STORE_FAST e
  DELETE_FAST e
  RERAISE 1
L9:
  RERAISE 0
L10:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L2..L3 -> handler=L4 depth=0 lasti=False
  EXC try=L4..L5 -> handler=L10 depth=1 lasti=True
  EXC try=L5..L7 -> handler=L8 depth=1 lasti=True
  EXC try=L8..L10 -> handler=L10 depth=1 lasti=True
END

def safe_makedirs(fdir):
    """pass"""
    if os.path.isdir(fdir):
        pass
    else:
        try:
            os.makedirs(fdir)
        except WindowsError as e:
            if 'Cannot create a file when that file already exists' in e:
                log.debug('relevant dir already exists')
            else:
                raise WindowsError(e)
    return True


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code convert_to_10>
  MAKE_FUNCTION 0
  STORE_NAME convert_to_10
  RETURN_CONST None
END
CODE convert_to_10(self)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + len
  LOAD_FAST self
  CALL 1
  LOAD_CONST 1
  COMPARE_OP <
  POP_JUMP_IF_FALSE L1
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + error
  LOAD_CONST 'no iocs available to modify'
  CALL 1
  POP_TOP
  RETURN_CONST False
L1:
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + info
  LOAD_CONST 'Converting IOCs from 1.1 to 1.0.'
  CALL 1
  POP_TOP
  BUILD_LIST 0
  STORE_FAST errors
  LOAD_FAST self
  LOAD_ATTR iocs
  GET_ITER
L2:
  EXTENDED_ARG 5
  FOR_ITER L37
  STORE_FAST iocid
  LOAD_CONST False
  STORE_FAST pruned
  LOAD_FAST self
  LOAD_ATTR iocs
  LOAD_FAST iocid
  BINARY_SUBSCR
  STORE_FAST ioc_obj_11
  LOAD_FAST ioc_obj_11
  LOAD_ATTR metadata
  STORE_FAST metadata
  LOAD_FAST metadata
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST './/short_description'
  CALL 1
  STORE_FAST name_11
  LOAD_FAST metadata
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST './/keywords'
  CALL 1
  STORE_FAST keywords_11
  LOAD_FAST metadata
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST './/description'
  CALL 1
  STORE_FAST description_11
  LOAD_FAST metadata
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST './/authored_by'
  CALL 1
  STORE_FAST author_11
  LOAD_FAST metadata
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST './/authored_date'
  CALL 1
  STORE_FAST created_date_11
  LOAD_FAST ioc_obj_11
  LOAD_ATTR root
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'last-modified'
  CALL 1
  STORE_FAST last_modified_date_11
  BUILD_LIST 0
  STORE_FAST links_11
  LOAD_FAST metadata
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST '//link'
  CALL 1
  GET_ITER
L3:
  FOR_ITER L4
  STORE_FAST link
  LOAD_FAST link
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'rel'
  CALL 1
  STORE_FAST link_rel
  LOAD_FAST link
  LOAD_ATTR text
  STORE_FAST link_text
  LOAD_FAST links_11
  LOAD_ATTR NULL|self + append
  LOAD_FAST link_rel
  LOAD_CONST None
  LOAD_FAST link_text
  BUILD_TUPLE 3
  CALL 1
  POP_TOP
  JUMP_BACKWARD L3
L4:
  END_FOR
  NOP
L5:
  LOAD_FAST ioc_obj_11
  LOAD_ATTR root
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST './/criteria'
  CALL 1
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST ioc_logic
L6:
  NOP
L7:
  LOAD_FAST ioc_logic
  LOAD_ATTR NULL|self + getchildren
  CALL 0
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST tlo_11
L8:
  LOAD_FAST tlo_11
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'id'
  CALL 1
  STORE_FAST tlo_id
  BUILD_MAP 0
  STORE_FAST comment_dict
  LOAD_FAST ioc_obj_11
  LOAD_ATTR parameters
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST '//param[@name="comment"]'
  CALL 1
  GET_ITER
L9:
  FOR_ITER L10
  STORE_FAST param
  LOAD_FAST param
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'ref-id'
  CALL 1
  STORE_FAST param_id
  LOAD_FAST param
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'value'
  CALL 1
  STORE_FAST param_text
  LOAD_FAST param_text
  LOAD_FAST comment_dict
  LOAD_FAST param_id
  STORE_SUBSCR
  JUMP_BACKWARD L9
L10:
  END_FOR
  LOAD_GLOBAL ioc_api
  LOAD_ATTR NULL|self + IOC
  LOAD_FAST name_11
  LOAD_FAST description_11
  LOAD_FAST author_11
  LOAD_FAST links_11
  LOAD_FAST keywords_11
  LOAD_FAST iocid
  KW_NAMES ('name', 'description', 'author', 'links', 'keywords', 'iocid')
  CALL 6
  STORE_FAST ioc_obj_10
  LOAD_FAST last_modified_date_11
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR attrib
  LOAD_CONST 'last-modified'
  STORE_SUBSCR
  LOAD_FAST ioc_obj_10
  LOAD_ATTR metadata
  LOAD_ATTR NULL|self + find
  LOAD_CONST 'authored_date'
  CALL 1
  STORE_FAST authored_date_node
  LOAD_FAST created_date_11
  LOAD_FAST authored_date_node
  STORE_ATTR text
  LOAD_CONST 'http://schemas.mandiant.com/2010/ioc'
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR attrib
  LOAD_CONST 'xmlns'
  STORE_SUBSCR
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR attrib
  LOAD_CONST 'published-date'
  DELETE_SUBSCR
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR NULL|self + remove
  LOAD_FAST ioc_obj_10
  LOAD_ATTR parameters
  CALL 1
  POP_TOP
  LOAD_CONST 'ioc'
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  STORE_ATTR tag
  LOAD_FAST ioc_obj_10
  LOAD_ATTR metadata
  STORE_FAST metadata_node
  LOAD_FAST ioc_obj_10
  LOAD_ATTR top_level_indicator
  LOAD_ATTR NULL|self + getparent
  CALL 0
  STORE_FAST criteria_node
  BUILD_MAP 0
  STORE_FAST metadata_dictionary
  LOAD_FAST metadata_node
  GET_ITER
L11:
  FOR_ITER L12
  STORE_FAST child
  LOAD_FAST child
  LOAD_FAST metadata_dictionary
  LOAD_FAST child
  LOAD_ATTR tag
  STORE_SUBSCR
  JUMP_BACKWARD L11
L12:
  END_FOR
  LOAD_GLOBAL METADATA_REQUIRED_10
  GET_ITER
L13:
  FOR_ITER L15
  STORE_FAST tag
  LOAD_FAST tag
  LOAD_FAST metadata_dictionary
  CONTAINS_OP 1
  POP_JUMP_IF_TRUE L14
  JUMP_BACKWARD L13
L14:
  LOAD_CONST 'IOC {} is missing required metadata: [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST iocid
  LOAD_FAST tag
  CALL 2
  STORE_FAST msg
  LOAD_GLOBAL NULL + DowngradeError
  LOAD_FAST msg
  CALL 1
  RAISE_VARARGS 1
L15:
  END_FOR
  LOAD_GLOBAL METADATA_ORDER_10
  GET_ITER
L16:
  FOR_ITER L18
  STORE_FAST tag
  LOAD_FAST tag
  LOAD_FAST metadata_dictionary
  CONTAINS_OP 0
  POP_JUMP_IF_TRUE L17
  JUMP_BACKWARD L16
L17:
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR NULL|self + append
  LOAD_FAST metadata_dictionary
  LOAD_ATTR NULL|self + get
  LOAD_FAST tag
  CALL 1
  CALL 1
  POP_TOP
  JUMP_BACKWARD L16
L18:
  END_FOR
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR NULL|self + remove
  LOAD_FAST metadata_node
  CALL 1
  POP_TOP
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR NULL|self + remove
  LOAD_FAST criteria_node
  CALL 1
  POP_TOP
  LOAD_CONST 'definition'
  LOAD_FAST criteria_node
  STORE_ATTR tag
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR NULL|self + append
  LOAD_FAST criteria_node
  CALL 1
  POP_TOP
  LOAD_FAST tlo_id
  LOAD_FAST ioc_obj_10
  LOAD_ATTR top_level_indicator
  LOAD_ATTR attrib
  LOAD_CONST 'id'
  STORE_SUBSCR
  LOAD_GLOBAL NULL + set
  CALL 0
  STORE_FAST ids_to_skip
  LOAD_GLOBAL NULL + set
  CALL 0
  STORE_FAST indicatoritems_to_remove
  LOAD_FAST self
  LOAD_ATTR openioc_11_only_conditions
  GET_ITER
L19:
  FOR_ITER L22
  STORE_FAST condition_type
  LOAD_FAST ioc_logic
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST '//IndicatorItem[@condition="%s"]'
  LOAD_FAST condition_type
  BINARY_OP %
  CALL 1
  GET_ITER
L20:
  FOR_ITER L21
  STORE_FAST elem
  LOAD_CONST True
  STORE_FAST pruned
  LOAD_FAST indicatoritems_to_remove
  LOAD_ATTR NULL|self + add
  LOAD_FAST elem
  CALL 1
  POP_TOP
  JUMP_BACKWARD L20
L21:
  END_FOR
  JUMP_BACKWARD L19
L22:
  END_FOR
  LOAD_FAST ioc_logic
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST '//IndicatorItem[@preserve-case="true"]'
  CALL 1
  GET_ITER
L23:
  FOR_ITER L24
  STORE_FAST elem
  LOAD_CONST True
  STORE_FAST pruned
  LOAD_FAST indicatoritems_to_remove
  LOAD_ATTR NULL|self + add
  LOAD_FAST elem
  CALL 1
  POP_TOP
  JUMP_BACKWARD L23
L24:
  END_FOR
  LOAD_FAST indicatoritems_to_remove
  GET_ITER
L25:
  FOR_ITER L30
  STORE_FAST elem
  LOAD_CONST None
  STORE_FAST nid
  LOAD_FAST elem
  STORE_FAST current
  LOAD_FAST nid
  LOAD_FAST tlo_id
  COMPARE_OP !=
  POP_JUMP_IF_TRUE L26
  JUMP_BACKWARD L25
L26:
  LOAD_FAST current
  LOAD_ATTR NULL|self + getparent
  CALL 0
  STORE_FAST parent
  LOAD_FAST parent
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'id'
  CALL 1
  STORE_FAST nid
  LOAD_FAST nid
  LOAD_FAST tlo_id
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L27
  LOAD_FAST current
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'id'
  CALL 1
  STORE_FAST current_id
  LOAD_FAST ids_to_skip
  LOAD_ATTR NULL|self + add
  LOAD_FAST current_id
  CALL 1
  POP_TOP
  JUMP_FORWARD L28
L27:
  LOAD_FAST parent
  STORE_FAST current
L28:
  LOAD_FAST nid
  LOAD_FAST tlo_id
  COMPARE_OP !=
  POP_JUMP_IF_FALSE L29
  JUMP_BACKWARD L26
L29:
  JUMP_BACKWARD L25
L30:
  END_FOR
  NOP
L31:
  LOAD_FAST self
  LOAD_ATTR NULL|self + convert_branch
  LOAD_FAST tlo_11
  LOAD_FAST ioc_obj_10
  LOAD_ATTR top_level_indicator
  LOAD_FAST ids_to_skip
  LOAD_FAST comment_dict
  CALL 4
  POP_TOP
L32:
  LOAD_FAST ioc_obj_10
  LOAD_ATTR top_level_indicator
  LOAD_ATTR NULL|self + getchildren
  CALL 0
  POP_JUMP_IF_TRUE L33
  LOAD_FAST self
  LOAD_ATTR null_pruned_iocs
  LOAD_ATTR NULL|self + add
  LOAD_FAST iocid
  CALL 1
  POP_TOP
  JUMP_FORWARD L34
L33:
  LOAD_FAST pruned
  LOAD_CONST True
  IS_OP 0
  POP_JUMP_IF_FALSE L34
  LOAD_FAST self
  LOAD_ATTR pruned_11_iocs
  LOAD_ATTR NULL|self + add
  LOAD_FAST iocid
  CALL 1
  POP_TOP
L34:
  LOAD_FAST ioc_obj_11
  LOAD_ATTR root
  LOAD_ATTR NULL|self + getprevious
  CALL 0
  STORE_FAST comment_node
  LOAD_FAST comment_node
  POP_JUMP_IF_NONE L36
L35:
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + debug
  LOAD_CONST 'found a comment node'
  CALL 1
  POP_TOP
  LOAD_GLOBAL et
  LOAD_ATTR NULL|self + Comment
  LOAD_FAST comment_node
  LOAD_ATTR text
  CALL 1
  STORE_FAST c
  LOAD_FAST ioc_obj_10
  LOAD_ATTR root
  LOAD_ATTR NULL|self + addprevious
  LOAD_FAST c
  CALL 1
  POP_TOP
  LOAD_FAST comment_node
  LOAD_ATTR NULL|self + getprevious
  CALL 0
  STORE_FAST comment_node
  LOAD_FAST comment_node
  POP_JUMP_IF_NONE L36
  JUMP_BACKWARD L35
L36:
  LOAD_FAST ioc_obj_10
  LOAD_FAST self
  LOAD_ATTR iocs_10
  LOAD_FAST iocid
  STORE_SUBSCR
  EXTENDED_ARG 5
  JUMP_BACKWARD L2
L37:
  END_FOR
  LOAD_FAST errors
  RETURN_VALUE
L38:
  PUSH_EXC_INFO
  LOAD_GLOBAL IndexError
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L40
  POP_TOP
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + exception
  LOAD_CONST 'Could not find criteria nodes for IOC [{}].  Did you attempt to convert OpenIOC 1.0 iocs?'
  LOAD_ATTR NULL|self + format
  LOAD_FAST iocid
  CALL 1
  CALL 1
  POP_TOP
  LOAD_FAST errors
  LOAD_ATTR NULL|self + append
  LOAD_FAST iocid
  CALL 1
  POP_TOP
L39:
  POP_EXCEPT
  EXTENDED_ARG 5
  JUMP_BACKWARD L2
L40:
  RERAISE 0
L41:
  COPY 3
  POP_EXCEPT
  RERAISE 1
L42:
  PUSH_EXC_INFO
  LOAD_GLOBAL IndexError
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L44
  POP_TOP
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + exception
  LOAD_CONST 'Could not find children for the top level criteria/children nodes for IOC [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST iocid
  CALL 1
  CALL 1
  POP_TOP
  LOAD_FAST errors
  LOAD_ATTR NULL|self + append
  LOAD_FAST iocid
  CALL 1
  POP_TOP
L43:
  POP_EXCEPT
  EXTENDED_ARG 5
  JUMP_BACKWARD L2
L44:
  RERAISE 0
L45:
  COPY 3
  POP_EXCEPT
  RERAISE 1
L46:
  PUSH_EXC_INFO
  LOAD_GLOBAL DowngradeError
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L48
  POP_TOP
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + exception
  LOAD_CONST 'Problem converting IOC [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST iocid
  CALL 1
  CALL 1
  POP_TOP
  LOAD_FAST errors
  LOAD_ATTR NULL|self + append
  LOAD_FAST iocid
  CALL 1
  POP_TOP
L47:
  POP_EXCEPT
  EXTENDED_ARG 5
  JUMP_BACKWARD L2
L48:
  LOAD_GLOBAL Exception
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L50
  POP_TOP
  LOAD_GLOBAL log
  LOAD_ATTR NULL|self + exception
  LOAD_CONST 'Unknown error occured while converting [{}]'
  LOAD_ATTR NULL|self + format
  LOAD_FAST iocid
  CALL 1
  CALL 1
  POP_TOP
  LOAD_FAST errors
  LOAD_ATTR NULL|self + append
  LOAD_FAST iocid
  CALL 1
  POP_TOP
L49:
  POP_EXCEPT
  EXTENDED_ARG 6
  JUMP_BACKWARD L2
L50:
  RERAISE 0
L51:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L5..L6 -> handler=L38 depth=1 lasti=False
  EXC try=L7..L8 -> handler=L42 depth=1 lasti=False
  EXC try=L31..L32 -> handler=L46 depth=1 lasti=False
  EXC try=L38..L39 -> handler=L41 depth=2 lasti=True
  EXC try=L40..L41 -> handler=L41 depth=2 lasti=True
  EXC try=L42..L43 -> handler=L45 depth=2 lasti=True
  EXC try=L44..L45 -> handler=L45 depth=2 lasti=True
  EXC try=L46..L47 -> handler=L51 depth=2 lasti=True
  EXC try=L48..L49 -> handler=L51 depth=2 lasti=True
  EXC try=L50..L51 -> handler=L51 depth=2 lasti=True
END

def convert_to_10(self):
    """pass"""
    if len(self) < 1:
        log.error('no iocs available to modify')
        return False
    log.info('Converting IOCs from 1.1 to 1.0.')
    errors = []
    for iocid in self.iocs:
        pruned = False
        ioc_obj_11 = self.iocs[iocid]
        metadata = ioc_obj_11.metadata
        name_11 = metadata.findtext('.//short_description')
        keywords_11 = metadata.findtext('.//keywords')
        description_11 = metadata.findtext('.//description')
        author_11 = metadata.findtext('.//authored_by')
        created_date_11 = metadata.findtext('.//authored_date')
        last_modified_date_11 = ioc_obj_11.root.get('last-modified')
        links_11 = []
        for link in metadata.xpath('//link'):
            link_rel = link.get('rel')
            link_text = link.text
            links_11.append((link_rel, None, link_text))
        try:
            ioc_logic = ioc_obj_11.root.xpath('.//criteria')[0]
        except IndexError:
            log.exception('Could not find criteria nodes for IOC [{}].  Did you attempt to convert OpenIOC 1.0 iocs?'.format(iocid))
            errors.append(iocid)
            continue
        try:
            tlo_11 = ioc_logic.getchildren()[0]
        except IndexError:
            log.exception('Could not find children for the top level criteria/children nodes for IOC [{}]'.format(iocid))
            errors.append(iocid)
            continue
        tlo_id = tlo_11.get('id')
        comment_dict = {}
        for param in ioc_obj_11.parameters.xpath('//param[@name="comment"]'):
            param_id = param.get('ref-id')
            param_text = param.findtext('value')
            comment_dict[param_id] = param_text
        ioc_obj_10 = ioc_api.IOC(name=name_11, description=description_11, author=author_11, links=links_11, keywords=keywords_11, iocid=iocid)
        ioc_obj_10.root.attrib['last-modified'] = last_modified_date_11
        authored_date_node = ioc_obj_10.metadata.find('authored_date')
        authored_date_node.text = created_date_11
        ioc_obj_10.root.attrib['xmlns'] = 'http://schemas.mandiant.com/2010/ioc'
        del ioc_obj_10.root.attrib['published-date']
        ioc_obj_10.root.remove(ioc_obj_10.parameters)
        ioc_obj_10.root.tag = 'ioc'
        metadata_node = ioc_obj_10.metadata
        criteria_node = ioc_obj_10.top_level_indicator.getparent()
        metadata_dictionary = {}
        for child in metadata_node:
            metadata_dictionary[child.tag] = child
        for tag in METADATA_REQUIRED_10:
            if tag not in metadata_dictionary:
                msg = 'IOC {} is missing required metadata: [{}]'.format(iocid, tag)
                raise DowngradeError(msg)
        for tag in METADATA_ORDER_10:
            if tag in metadata_dictionary:
                ioc_obj_10.root.append(metadata_dictionary.get(tag))
        ioc_obj_10.root.remove(metadata_node)
        ioc_obj_10.root.remove(criteria_node)
        criteria_node.tag = 'definition'
        ioc_obj_10.root.append(criteria_node)
        ioc_obj_10.top_level_indicator.attrib['id'] = tlo_id
        ids_to_skip = set()
        indicatoritems_to_remove = set()
        for condition_type in self.openioc_11_only_conditions:
            for elem in ioc_logic.xpath('//IndicatorItem[@condition="%s"]' % condition_type):
                pruned = True
                indicatoritems_to_remove.add(elem)
        for elem in ioc_logic.xpath('//IndicatorItem[@preserve-case="true"]'):
            pruned = True
            indicatoritems_to_remove.add(elem)
        for elem in indicatoritems_to_remove:
            nid = None
            current = elem
            while nid != tlo_id:
                parent = current.getparent()
                nid = parent.get('id')
                if nid == tlo_id:
                    current_id = current.get('id')
                    ids_to_skip.add(current_id)
                else:
                    current = parent
        try:
            self.convert_branch(tlo_11, ioc_obj_10.top_level_indicator, ids_to_skip, comment_dict)
        except DowngradeError:
            log.exception('Problem converting IOC [{}]'.format(iocid))
            errors.append(iocid)
            continue
        except Exception:
            log.exception('Unknown error occured while converting [{}]'.format(iocid))
            errors.append(iocid)
            continue
        if not ioc_obj_10.top_level_indicator.getchildren():
            self.null_pruned_iocs.add(iocid)
        elif pruned is True:
            self.pruned_11_iocs.add(iocid)
        comment_node = ioc_obj_11.root.getprevious()
        while comment_node is not None:
            log.debug('found a comment node')
            c = et.Comment(comment_node.text)
            ioc_obj_10.root.addprevious(c)
            comment_node = comment_node.getprevious()
        self.iocs_10[iocid] = ioc_obj_10
    return errors


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (None,)
  LOAD_CONST <code convert_branch>
  MAKE_FUNCTION defaults
  STORE_NAME convert_branch
  RETURN_CONST None
END
CODE convert_branch(self, old_node, new_node, ids_to_skip, comment_dict)
  DOC 'pass'
  RESUME 0
  LOAD_CONST 'Indicator'
  STORE_FAST expected_tag
  LOAD_FAST old_node
  LOAD_ATTR tag
  LOAD_FAST expected_tag
  COMPARE_OP !=
  POP_JUMP_IF_FALSE L1
  LOAD_GLOBAL NULL + DowngradeError
  LOAD_CONST 'old_node expected tag is [%s]'
  LOAD_FAST expected_tag
  BINARY_OP %
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_FAST comment_dict
  POP_JUMP_IF_TRUE L2
  BUILD_MAP 0
  STORE_FAST comment_dict
L2:
  LOAD_FAST old_node
  LOAD_ATTR NULL|self + getchildren
  CALL 0
  GET_ITER
L3:
  EXTENDED_ARG 1
  FOR_ITER L11
  STORE_FAST node
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'id'
  CALL 1
  STORE_FAST node_id
  LOAD_FAST node_id
  LOAD_FAST ids_to_skip
  CONTAINS_OP 0
  POP_JUMP_IF_FALSE L4
  JUMP_BACKWARD L3
L4:
  LOAD_FAST node
  LOAD_ATTR tag
  LOAD_CONST 'IndicatorItem'
  COMPARE_OP ==
  EXTENDED_ARG 1
  POP_JUMP_IF_FALSE L8
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'negate'
  CALL 1
  STORE_FAST negation
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'condition'
  CALL 1
  STORE_FAST condition
  LOAD_CONST 'true'
  LOAD_FAST negation
  LOAD_ATTR NULL|self + lower
  CALL 0
  CONTAINS_OP 0
  POP_JUMP_IF_FALSE L5
  LOAD_FAST condition
  LOAD_CONST 'not'
  BINARY_OP +
  STORE_FAST new_condition
  JUMP_FORWARD L6
L5:
  LOAD_FAST condition
  STORE_FAST new_condition
L6:
  LOAD_FAST node
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST 'Context/@document'
  CALL 1
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST document
  LOAD_FAST node
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST 'Context/@search'
  CALL 1
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST search
  LOAD_FAST node
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST 'Content/@type'
  CALL 1
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST content_type
  LOAD_FAST node
  LOAD_ATTR NULL|self + findtext
  LOAD_CONST 'Content'
  CALL 1
  STORE_FAST content
  LOAD_FAST node
  LOAD_ATTR NULL|self + xpath
  LOAD_CONST 'Context/@type'
  CALL 1
  LOAD_CONST 0
  BINARY_SUBSCR
  STORE_FAST context_type
  LOAD_GLOBAL ioc_api
  LOAD_ATTR NULL|self + make_indicatoritem_node
  LOAD_FAST condition
  LOAD_FAST document
  LOAD_FAST search
  LOAD_FAST content_type
  LOAD_FAST content
  LOAD_FAST context_type
  LOAD_FAST node_id
  KW_NAMES ('condition', 'document', 'search', 'content_type', 'content', 'context_type', 'nid')
  CALL 7
  STORE_FAST new_ii_node
  LOAD_FAST new_condition
  LOAD_FAST new_ii_node
  LOAD_ATTR attrib
  LOAD_CONST 'condition'
  STORE_SUBSCR
  LOAD_FAST node_id
  LOAD_FAST comment_dict
  CONTAINS_OP 0
  POP_JUMP_IF_FALSE L7
  LOAD_FAST comment_dict
  LOAD_FAST node_id
  BINARY_SUBSCR
  STORE_FAST comment
  LOAD_GLOBAL et
  LOAD_ATTR NULL|self + Element
  LOAD_CONST 'Comment'
  CALL 1
  STORE_FAST comment_node
  LOAD_FAST comment
  LOAD_FAST comment_node
  STORE_ATTR text
  LOAD_FAST new_ii_node
  LOAD_ATTR NULL|self + append
  LOAD_FAST comment_node
  CALL 1
  POP_TOP
L7:
  LOAD_FAST new_ii_node
  LOAD_ATTR attrib
  LOAD_CONST 'negate'
  DELETE_SUBSCR
  LOAD_FAST new_ii_node
  LOAD_ATTR attrib
  LOAD_CONST 'preserve-case'
  DELETE_SUBSCR
  LOAD_FAST new_node
  LOAD_ATTR NULL|self + append
  LOAD_FAST new_ii_node
  CALL 1
  POP_TOP
  EXTENDED_ARG 1
  JUMP_BACKWARD L3
L8:
  LOAD_FAST node
  LOAD_ATTR tag
  LOAD_CONST 'Indicator'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L10
  LOAD_FAST node
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'operator'
  CALL 1
  STORE_FAST operator
  LOAD_FAST operator
  LOAD_ATTR NULL|self + upper
  CALL 0
  LOAD_CONST ('OR', 'AND')
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L9
  LOAD_GLOBAL NULL + DowngradeError
  LOAD_CONST 'Indicator@operator is not AND/OR. ['
  LOAD_FAST node_id
  FORMAT_VALUE str
  LOAD_CONST '] has ['
  LOAD_FAST operator
  FORMAT_VALUE str
  LOAD_CONST ']'
  BUILD_STRING 5
  CALL 1
  RAISE_VARARGS 1
L9:
  LOAD_GLOBAL ioc_api
  LOAD_ATTR NULL|self + make_indicator_node
  LOAD_FAST operator
  LOAD_FAST node_id
  CALL 2
  STORE_FAST new_i_node
  LOAD_FAST new_node
  LOAD_ATTR NULL|self + append
  LOAD_FAST new_i_node
  CALL 1
  POP_TOP
  LOAD_FAST self
  LOAD_ATTR NULL|self + convert_branch
  LOAD_FAST node
  LOAD_FAST new_i_node
  LOAD_FAST ids_to_skip
  LOAD_FAST comment_dict
  CALL 4
  POP_TOP
  EXTENDED_ARG 1
  JUMP_BACKWARD L3
L10:
  LOAD_GLOBAL NULL + DowngradeError
  LOAD_CONST 'node is not a Indicator/IndicatorItem'
  CALL 1
  RAISE_VARARGS 1
L11:
  END_FOR
  RETURN_CONST True
END

def convert_branch(self, old_node, new_node, ids_to_skip, comment_dict=None):
    """pass"""
    expected_tag = 'Indicator'
    if old_node.tag != expected_tag:
        raise DowngradeError('old_node expected tag is [%s]' % expected_tag)
    if not comment_dict:
        comment_dict = {}
    for node in old_node.getchildren():
        node_id = node.get('id')
        if node_id in ids_to_skip:
            continue
        if node.tag == 'IndicatorItem':
            negation = node.get('negate')
            condition = node.get('condition')
            if 'true' in negation.lower():
                new_condition = condition + 'not'
            else:
                new_condition = condition
            document = node.xpath('Context/@document')[0]
            search = node.xpath('Context/@search')[0]
            content_type = node.xpath('Content/@type')[0]
            content = node.findtext('Content')
            context_type = node.xpath('Context/@type')[0]
            new_ii_node = ioc_api.make_indicatoritem_node(condition=condition, document=document, search=search, content_type=content_type, content=content, context_type=context_type, nid=node_id)
            new_ii_node.attrib['condition'] = new_condition
            if node_id in comment_dict:
                comment = comment_dict[node_id]
                comment_node = et.Element('Comment')
                comment_node.text = comment
                new_ii_node.append(comment_node)
            del new_ii_node.attrib['negate']
            del new_ii_node.attrib['preserve-case']
            new_node.append(new_ii_node)
        elif node.tag == 'Indicator':
            operator = node.get('operator')
            if operator.upper() not in ['OR', 'AND']:
                raise DowngradeError('Indicator@operator is not AND/OR. [%s] has [%s]' % (node_id, operator))
            new_i_node = ioc_api.make_indicator_node(operator, node_id)
            new_node.append(new_i_node)
            self.convert_branch(node, new_i_node, ids_to_skip, comment_dict)
        else:
            raise DowngradeError('node is not a Indicator/IndicatorItem')
    return True


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code create>
  MAKE_FUNCTION 0
  STORE_NAME create
  RETURN_CONST None
END
CODE create(self, permission)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR _manager
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'GET'
  LOAD_CONST 'single'
  LOAD_CONST 'id'
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR id
  BUILD_MAP 1
  CALL 4
  STORE_FAST parent_url
  LOAD_FAST parent_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url_path
  LOAD_FAST self
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'POST'
  LOAD_CONST 'single'
  CALL 3
  BINARY_OP +
  STORE_FAST target_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + request
  LOAD_CONST 'POST'
  LOAD_FAST target_url
  LOAD_FAST permission
  LOAD_ATTR NULL|self + _serialize
  CALL 0
  KW_NAMES ('json',)
  CALL 3
  STORE_FAST r
  LOAD_FAST permission
  LOAD_ATTR NULL|self + _deserialize
  LOAD_FAST r
  LOAD_ATTR NULL|self + json
  CALL 0
  LOAD_FAST self
  CALL 2
  RETURN_VALUE
END

def create(self, permission):
    """pass"""
    parent_url = self.client.get_url(self.parent_object._manager._URL_KEY, 'GET', 'single', {'id': self.parent_object.id})
    target_url = parent_url + self.client.get_url_path(self._URL_KEY, 'POST', 'single')
    r = self.client.request('POST', target_url, json=permission._serialize())
    return permission._deserialize(r.json(), self)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code set>
  MAKE_FUNCTION 0
  STORE_NAME set
  RETURN_CONST None
END
CODE set(self, permissions)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR _manager
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'GET'
  LOAD_CONST 'single'
  LOAD_CONST 'id'
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR id
  BUILD_MAP 1
  CALL 4
  STORE_FAST parent_url
  LOAD_FAST parent_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url_path
  LOAD_FAST self
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'PUT'
  LOAD_CONST 'multi'
  CALL 3
  BINARY_OP +
  STORE_FAST target_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + request
  LOAD_CONST 'PUT'
  LOAD_FAST target_url
  LOAD_FAST permissions
  KW_NAMES ('json',)
  CALL 3
  STORE_FAST r
  LOAD_FAST r
  LOAD_ATTR status_code
  LOAD_CONST 201
  COMPARE_OP !=
  POP_JUMP_IF_FALSE L1
  LOAD_GLOBAL exceptions
  LOAD_ATTR NULL|self + ServerError
  LOAD_CONST 'Expected 201 response, got '
  LOAD_FAST r
  LOAD_ATTR status_code
  FORMAT_VALUE str
  LOAD_CONST ': '
  LOAD_FAST target_url
  FORMAT_VALUE str
  BUILD_STRING 4
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_FAST self
  LOAD_ATTR NULL|self + list
  CALL 0
  RETURN_VALUE
END

def set(self, permissions):
    """pass"""
    parent_url = self.client.get_url(self.parent_object._manager._URL_KEY, 'GET', 'single', {'id': self.parent_object.id})
    target_url = parent_url + self.client.get_url_path(self._URL_KEY, 'PUT', 'multi')
    r = self.client.request('PUT', target_url, json=permissions)
    if r.status_code != 201:
        raise exceptions.ServerError('Expected 201 response, got %s: %s' % (r.status_code, target_url))
    return self.list()


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code list>
  MAKE_FUNCTION 0
  STORE_NAME list
  RETURN_CONST None
END
CODE list(self)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR _manager
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'GET'
  LOAD_CONST 'single'
  LOAD_CONST 'id'
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR id
  BUILD_MAP 1
  CALL 4
  STORE_FAST parent_url
  LOAD_FAST parent_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url_path
  LOAD_FAST self
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'GET'
  LOAD_CONST 'multi'
  CALL 3
  BINARY_OP +
  STORE_FAST target_url
  LOAD_GLOBAL base
  LOAD_ATTR NULL|self + Query
  LOAD_FAST self
  LOAD_FAST target_url
  CALL 2
  RETURN_VALUE
END

def list(self):
    """pass"""
    parent_url = self.client.get_url(self.parent_object._manager._URL_KEY, 'GET', 'single', {'id': self.parent_object.id})
    target_url = parent_url + self.client.get_url_path(self._URL_KEY, 'GET', 'multi')
    return base.Query(self, target_url)


Input:
CODE <module>()
  RESUME 0
  BUILD_LIST 0
  BUILD_TUPLE 1
  LOAD_CONST <code get>
  MAKE_FUNCTION defaults
  STORE_NAME get
  RETURN_CONST None
END
CODE get(self, permission_id, expand)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR _manager
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'GET'
  LOAD_CONST 'single'
  LOAD_CONST 'id'
  LOAD_FAST self
  LOAD_ATTR parent_object
  LOAD_ATTR id
  BUILD_MAP 1
  CALL 4
  STORE_FAST parent_url
  LOAD_FAST parent_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url_path
  LOAD_FAST self
  LOAD_ATTR _URL_KEY
  LOAD_CONST 'GET'
  LOAD_CONST 'single'
  LOAD_CONST 'permission_id'
  LOAD_FAST permission_id
  BUILD_MAP 1
  CALL 4
  BINARY_OP +
  STORE_FAST target_url
  LOAD_FAST self
  LOAD_ATTR NULL|self + _get
  LOAD_FAST target_url
  LOAD_FAST expand
  KW_NAMES ('expand',)
  CALL 2
  RETURN_VALUE
END

def get(self, permission_id, expand=[]):
    """pass"""
    parent_url = self.client.get_url(self.parent_object._manager._URL_KEY, 'GET', 'single', {'id': self.parent_object.id})
    target_url = parent_url + self.client.get_url_path(self._URL_KEY, 'GET', 'single', {'permission_id': permission_id})
    return self._get(target_url, expand=expand)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code get_config>
  MAKE_FUNCTION 0
  STORE_NAME get_config
  RETURN_CONST None
END
CODE get_config()
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + get_configpath
  CALL 0
  STORE_FAST configpath
  LOAD_FAST configpath
  LOAD_ATTR NULL|self + exists
  CALL 0
  POP_JUMP_IF_TRUE L1
  LOAD_GLOBAL NULL + IOError
  LOAD_CONST 'Config file {} not found.'
  LOAD_ATTR NULL|self + format
  LOAD_GLOBAL NULL + str
  LOAD_FAST configpath
  CALL 1
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_GLOBAL configparser
  LOAD_ATTR NULL|self + ConfigParser
  CALL 0
  STORE_FAST config
  LOAD_FAST config
  LOAD_ATTR NULL|self + read
  LOAD_GLOBAL NULL + str
  LOAD_FAST configpath
  CALL 1
  CALL 1
  POP_TOP
  LOAD_FAST config
  RETURN_VALUE
END

def get_config():
    """pass"""
    configpath = get_configpath()
    if not configpath.exists():
        raise IOError('Config file {} not found.'.format(str(configpath)))
    else:
        config = configparser.ConfigParser()
        config.read(str(configpath))
        return config


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code set_database_path>
  MAKE_FUNCTION 0
  STORE_NAME set_database_path
  RETURN_CONST None
END
CODE set_database_path(dbfolder)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + get_configpath
  CALL 0
  STORE_FAST configpath
  NOP
L1:
  LOAD_GLOBAL NULL + get_config
  CALL 0
  STORE_FAST d
L2:
  LOAD_FAST dbfolder
  LOAD_FAST d
  LOAD_CONST 'pyciss_db'
  BINARY_SUBSCR
  LOAD_CONST 'path'
  STORE_SUBSCR
  LOAD_FAST configpath
  LOAD_ATTR NULL|self + open
  LOAD_CONST 'w'
  CALL 1
  BEFORE_WITH
L3:
  STORE_FAST f
  LOAD_FAST d
  LOAD_ATTR NULL|self + write
  LOAD_FAST f
  CALL 1
  POP_TOP
L4:
  LOAD_CONST None
  LOAD_CONST None
  LOAD_CONST None
  CALL 2
  POP_TOP
L5:
  LOAD_GLOBAL NULL + print
  LOAD_CONST 'Saved database path into {}.'
  LOAD_ATTR NULL|self + format
  LOAD_FAST configpath
  CALL 1
  CALL 1
  POP_TOP
  RETURN_CONST None
L6:
  PUSH_EXC_INFO
  LOAD_GLOBAL IOError
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L8
  POP_TOP
  LOAD_GLOBAL configparser
  LOAD_ATTR NULL|self + ConfigParser
  CALL 0
  STORE_FAST d
  BUILD_MAP 0
  LOAD_FAST d
  LOAD_CONST 'pyciss_db'
  STORE_SUBSCR
L7:
  POP_EXCEPT
  JUMP_BACKWARD L2
L8:
  RERAISE 0
L9:
  COPY 3
  POP_EXCEPT
  RERAISE 1
L10:
  PUSH_EXC_INFO
  WITH_EXCEPT_START
  POP_JUMP_IF_TRUE L11
  RERAISE 2
L11:
  POP_TOP
L12:
  POP_EXCEPT
  POP_TOP
  POP_TOP
  JUMP_BACKWARD L5
L13:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L1..L2 -> handler=L6 depth=0 lasti=False
  EXC try=L3..L4 -> handler=L10 depth=1 lasti=True
  EXC try=L6..L7 -> handler=L9 depth=1 lasti=True
  EXC try=L8..L9 -> handler=L9 depth=1 lasti=True
  EXC try=L10..L12 -> handler=L13 depth=3 lasti=True
END

def set_database_path(dbfolder):
    """pass"""
    configpath = get_configpath()
    try:
        d = get_config()
    except IOError:
        d = configparser.ConfigParser()
        d['pyciss_db'] = {}
    d['pyciss_db']['path'] = dbfolder
    with configpath.open('w') as f:
        d.write(f)
    print('Saved database path into {}.'.format(configpath))


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code get_db_root>
  MAKE_FUNCTION 0
  STORE_NAME get_db_root
  RETURN_CONST None
END
CODE get_db_root()
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + get_config
  CALL 0
  STORE_FAST d
  LOAD_GLOBAL NULL + Path
  LOAD_FAST d
  LOAD_CONST 'pyciss_db'
  BINARY_SUBSCR
  LOAD_CONST 'path'
  BINARY_SUBSCR
  CALL 1
  STORE_FAST dbroot
  LOAD_FAST dbroot
  LOAD_ATTR NULL|self + mkdir
  LOAD_CONST True
  KW_NAMES ('exist_ok',)
  CALL 1
  POP_TOP
  LOAD_FAST dbroot
  RETURN_VALUE
END

def get_db_root():
    """pass"""
    d = get_config()
    dbroot = Path(d['pyciss_db']['path'])
    dbroot.mkdir(exist_ok=True)
    return dbroot


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code print_db_stats>
  MAKE_FUNCTION 0
  STORE_NAME print_db_stats
  RETURN_CONST None
END
CODE print_db_stats()
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + get_db_root
  CALL 0
  STORE_FAST dbroot
  LOAD_GLOBAL NULL + len
  LOAD_GLOBAL NULL + list
  LOAD_FAST dbroot
  LOAD_ATTR NULL|self + glob
  LOAD_CONST '[N,W]*'
  CALL 1
  CALL 1
  CALL 1
  STORE_FAST n_ids
  LOAD_GLOBAL NULL + print
  LOAD_CONST 'Number of WACs and NACs in database: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST n_ids
  CALL 1
  CALL 1
  POP_TOP
  LOAD_GLOBAL NULL + print
  LOAD_CONST 'These kind of data are in the database: (returning pd.DataFrame)'
  CALL 1
  POP_TOP
  BUILD_MAP 0
  STORE_FAST d
  LOAD_GLOBAL PathManager
  LOAD_ATTR extensions
  LOAD_ATTR NULL|self + items
  CALL 0
  GET_ITER
L1:
  FOR_ITER L2
  UNPACK_SEQUENCE 2
  STORE_FAST key
  STORE_FAST val
  LOAD_GLOBAL NULL + len
  LOAD_GLOBAL NULL + list
  LOAD_FAST dbroot
  LOAD_ATTR NULL|self + glob
  LOAD_CONST '**/*'
  LOAD_FAST val
  BINARY_OP +
  CALL 1
  CALL 1
  CALL 1
  BUILD_LIST 1
  LOAD_FAST d
  LOAD_FAST key
  STORE_SUBSCR
  JUMP_BACKWARD L1
L2:
  END_FOR
  LOAD_GLOBAL pd
  LOAD_ATTR NULL|self + DataFrame
  LOAD_FAST d
  CALL 1
  RETURN_VALUE
END

def print_db_stats():
    """pass"""
    dbroot = get_db_root()
    n_ids = len(list(dbroot.glob('[N,W]*')))
    print('Number of WACs and NACs in database: {}'.format(n_ids))
    print('These kind of data are in the database: (returning pd.DataFrame)')
    d = {}
    for key, val in PathManager.extensions.items():
        d[key] = [len(list(dbroot.glob('**/*' + val)))]
    return pd.DataFrame(d)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code is_lossy>
  MAKE_FUNCTION 0
  STORE_NAME is_lossy
  RETURN_CONST None
END
CODE is_lossy(label)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + getkey
  LOAD_FAST label
  LOAD_CONST 'INST_CMPRS_TYPE'
  KW_NAMES ('from_', 'keyword')
  CALL 2
  LOAD_ATTR NULL|self + decode
  CALL 0
  LOAD_ATTR NULL|self + strip
  CALL 0
  STORE_FAST val
  LOAD_FAST val
  LOAD_CONST 'LOSSY'
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L1
  RETURN_CONST True
L1:
  RETURN_CONST False
END

def is_lossy(label):
    """pass"""
    val = getkey(from_=label, keyword='INST_CMPRS_TYPE').decode().strip()
    if val == 'LOSSY':
        return True
    else:
        return False


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST (None,)
  LOAD_CONST <code download_and_calibrate_parallel>
  MAKE_FUNCTION defaults
  STORE_NAME download_and_calibrate_parallel
  RETURN_CONST None
END
CODE download_and_calibrate_parallel(list_of_ids, n)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + setup_cluster
  LOAD_FAST n
  KW_NAMES ('n_cores',)
  CALL 1
  POP_TOP
  LOAD_GLOBAL NULL + Client
  CALL 0
  STORE_FAST c
  LOAD_FAST c
  LOAD_ATTR NULL|self + load_balanced_view
  CALL 0
  STORE_FAST lbview
  LOAD_FAST lbview
  LOAD_ATTR NULL|self + map_async
  LOAD_GLOBAL download_and_calibrate
  LOAD_FAST list_of_ids
  CALL 2
  POP_TOP
  LOAD_GLOBAL subprocess
  LOAD_ATTR NULL|self + Popen
  BUILD_LIST 0
  LOAD_CONST ('ipcluster', 'stop', '--quiet')
  LIST_EXTEND 1
  CALL 1
  POP_TOP
  RETURN_CONST None
END

def download_and_calibrate_parallel(list_of_ids, n=None):
    """pass"""
    setup_cluster(n_cores=n)
    c = Client()
    lbview = c.load_balanced_view()
    lbview.map_async(download_and_calibrate, list_of_ids)
    subprocess.Popen(['ipcluster', 'stop', '--quiet'])


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code _set_supported_content_type>
  MAKE_FUNCTION 0
  STORE_NAME _set_supported_content_type
  RETURN_CONST None
END
CODE _set_supported_content_type(self, content_types_supported)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST content_types_supported
  LOAD_GLOBAL list
  CALL 2
  POP_JUMP_IF_TRUE L1
  LOAD_GLOBAL NULL + TypeError
  LOAD_CONST "Settings 'READTIME_CONTENT_SUPPORT' must bea list of content types."
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_FAST content_types_supported
  LOAD_FAST self
  STORE_ATTR content_type_supported
  RETURN_CONST None
END

def _set_supported_content_type(self, content_types_supported):
    """pass"""
    if not isinstance(content_types_supported, list):
        raise TypeError("Settings 'READTIME_CONTENT_SUPPORT' must bea list of content types.")
    self.content_type_supported = content_types_supported


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code _set_lang_settings>
  MAKE_FUNCTION 0
  STORE_NAME _set_lang_settings
  RETURN_CONST None
END
CODE _set_lang_settings(self, lang_settings)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST lang_settings
  LOAD_GLOBAL int
  CALL 2
  STORE_FAST is_int
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST lang_settings
  LOAD_GLOBAL dict
  CALL 2
  STORE_FAST is_dict
  LOAD_FAST is_int
  POP_JUMP_IF_TRUE L1
  LOAD_FAST is_dict
  POP_JUMP_IF_TRUE L1
  LOAD_GLOBAL NULL + TypeError
  LOAD_CONST "Settings 'READTIME_WPM' must be either an int,or a dict with settings per language."
  CALL 1
  RAISE_VARARGS 1
L1:
  LOAD_FAST is_int
  POP_JUMP_IF_FALSE L2
  LOAD_FAST lang_settings
  LOAD_FAST self
  LOAD_ATTR lang_settings
  LOAD_CONST 'default'
  BINARY_SUBSCR
  LOAD_CONST 'wpm'
  STORE_SUBSCR
  RETURN_CONST None
L2:
  LOAD_FAST is_dict
  POP_JUMP_IF_FALSE L11
  LOAD_FAST lang_settings
  LOAD_ATTR NULL|self + items
  CALL 0
  GET_ITER
L3:
  FOR_ITER L10
  UNPACK_SEQUENCE 2
  STORE_FAST lang
  STORE_FAST conf
  LOAD_CONST 'wpm'
  LOAD_FAST conf
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L4
  LOAD_GLOBAL NULL + KeyError
  LOAD_CONST 'Missing wpm value for thelanguage: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST lang
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L4:
  LOAD_GLOBAL NULL + isinstance
  LOAD_FAST conf
  LOAD_CONST 'wpm'
  BINARY_SUBSCR
  LOAD_GLOBAL int
  CALL 2
  POP_JUMP_IF_TRUE L5
  LOAD_GLOBAL NULL + TypeError
  LOAD_CONST 'WPM is not an integer for the language: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST lang
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L5:
  LOAD_CONST 'min_singular'
  LOAD_FAST conf
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L6
  LOAD_GLOBAL NULL + KeyError
  LOAD_CONST 'Missing singular form for "minute" for the language: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST lang
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L6:
  LOAD_CONST 'min_plural'
  LOAD_FAST conf
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L7
  LOAD_GLOBAL NULL + KeyError
  LOAD_CONST 'Missing plural form for "minutes" for the language: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST lang
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L7:
  LOAD_CONST 'sec_singular'
  LOAD_FAST conf
  CONTAINS_OP 1
  POP_JUMP_IF_FALSE L8
  LOAD_GLOBAL NULL + KeyError
  LOAD_CONST 'Missing singular form for "second" for the language: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST lang
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L8:
  LOAD_CONST 'sec_plural'
  LOAD_FAST conf
  CONTAINS_OP 1
  POP_JUMP_IF_TRUE L9
  JUMP_BACKWARD L3
L9:
  LOAD_GLOBAL NULL + KeyError
  LOAD_CONST 'Missing plural form for "seconds" for the language: {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST lang
  CALL 1
  CALL 1
  RAISE_VARARGS 1
L10:
  END_FOR
  LOAD_FAST lang_settings
  LOAD_FAST self
  STORE_ATTR lang_settings
  RETURN_CONST None
L11:
  RETURN_CONST None
END

def _set_lang_settings(self, lang_settings):
    """pass"""
    is_int = isinstance(lang_settings, int)
    is_dict = isinstance(lang_settings, dict)
    if not is_int and (not is_dict):
        raise TypeError("Settings 'READTIME_WPM' must be either an int,or a dict with settings per language.")
    if is_int:
        self.lang_settings['default']['wpm'] = lang_settings
    elif is_dict:
        for lang, conf in lang_settings.items():
            if 'wpm' not in conf:
                raise KeyError('Missing wpm value for thelanguage: {}'.format(lang))
            if not isinstance(conf['wpm'], int):
                raise TypeError('WPM is not an integer for the language: {}'.format(lang))
            if 'min_singular' not in conf:
                raise KeyError('Missing singular form for "minute" for the language: {}'.format(lang))
            if 'min_plural' not in conf:
                raise KeyError('Missing plural form for "minutes" for the language: {}'.format(lang))
            if 'sec_singular' not in conf:
                raise KeyError('Missing singular form for "second" for the language: {}'.format(lang))
            if 'sec_plural' not in conf:
                raise KeyError('Missing plural form for "seconds" for the language: {}'.format(lang))
        self.lang_settings = lang_settings


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code initialize_settings>
  MAKE_FUNCTION 0
  STORE_NAME initialize_settings
  RETURN_CONST None
END
CODE initialize_settings(self, sender)
  DOC 'pass'
  RESUME 0
  NOP
L1:
  LOAD_CONST True
  LOAD_FAST self
  STORE_ATTR initialized
  LOAD_FAST sender
  LOAD_ATTR settings
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'READTIME_CONTENT_SUPPORT'
  LOAD_FAST self
  LOAD_ATTR content_type_supported
  CALL 2
  STORE_FAST settings_content_types
  LOAD_FAST self
  LOAD_ATTR NULL|self + _set_supported_content_type
  LOAD_FAST settings_content_types
  CALL 1
  POP_TOP
  LOAD_FAST sender
  LOAD_ATTR settings
  LOAD_ATTR NULL|self + get
  LOAD_CONST 'READTIME_WPM'
  LOAD_FAST self
  LOAD_ATTR lang_settings
  CALL 2
  STORE_FAST lang_settings
  LOAD_FAST self
  LOAD_ATTR NULL|self + _set_lang_settings
  LOAD_FAST lang_settings
  CALL 1
  POP_TOP
L2:
  RETURN_CONST None
L3:
  PUSH_EXC_INFO
  LOAD_GLOBAL Exception
  CHECK_EXC_MATCH
  POP_JUMP_IF_FALSE L6
  STORE_FAST e
L4:
  LOAD_GLOBAL NULL + Exception
  LOAD_CONST 'ReadTime Plugin: %s'
  LOAD_GLOBAL NULL + str
  LOAD_FAST e
  CALL 1
  BINARY_OP %
  CALL 1
  RAISE_VARARGS 1
L5:
  LOAD_CONST None
  STORE_FAST e
  DELETE_FAST e
  RERAISE 1
L6:
  RERAISE 0
L7:
  COPY 3
  POP_EXCEPT
  RERAISE 1
  EXC try=L1..L2 -> handler=L3 depth=0 lasti=False
  EXC try=L3..L4 -> handler=L7 depth=1 lasti=True
  EXC try=L4..L5 -> handler=L5 depth=1 lasti=True
  EXC try=L5..L7 -> handler=L7 depth=1 lasti=True
END

def initialize_settings(self, sender):
    """pass"""
    try:
        self.initialized = True
        settings_content_types = sender.settings.get('READTIME_CONTENT_SUPPORT', self.content_type_supported)
        self._set_supported_content_type(settings_content_types)
        lang_settings = sender.settings.get('READTIME_WPM', self.lang_settings)
        self._set_lang_settings(lang_settings)
    except Exception as e:
        raise Exception('ReadTime Plugin: %s' % str(e))


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code read_time>
  MAKE_FUNCTION 0
  STORE_NAME read_time
  RETURN_CONST None
END
CODE read_time(self, content)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL NULL + get_class_name
  LOAD_FAST content
  CALL 1
  LOAD_FAST self
  LOAD_ATTR content_type_supported
  CONTAINS_OP 0
  POP_JUMP_IF_FALSE L2
  LOAD_GLOBAL NULL + hasattr
  LOAD_FAST content
  LOAD_CONST 'readtime'
  CALL 2
  POP_JUMP_IF_FALSE L1
  RETURN_CONST None
L1:
  LOAD_FAST self
  LOAD_ATTR lang_settings
  LOAD_CONST 'default'
  BINARY_SUBSCR
  STORE_FAST default_lang_conf
  LOAD_FAST self
  LOAD_ATTR lang_settings
  LOAD_ATTR NULL|self + get
  LOAD_FAST content
  LOAD_ATTR lang
  LOAD_FAST default_lang_conf
  CALL 2
  STORE_FAST lang_conf
  LOAD_FAST lang_conf
  LOAD_CONST 'wpm'
  BINARY_SUBSCR
  STORE_FAST avg_reading_wpm
  LOAD_GLOBAL NULL + len
  LOAD_FAST content
  LOAD_ATTR _content
  LOAD_ATTR NULL|self + split
  CALL 0
  CALL 1
  STORE_FAST num_words
  LOAD_FAST num_words
  LOAD_FAST avg_reading_wpm
  BINARY_OP //
  STORE_FAST minutes
  LOAD_GLOBAL NULL + int
  LOAD_FAST num_words
  LOAD_FAST avg_reading_wpm
  BINARY_OP /
  LOAD_CONST 60
  BINARY_OP *
  LOAD_FAST minutes
  LOAD_CONST 60
  BINARY_OP *
  BINARY_OP -
  CALL 1
  STORE_FAST seconds
  LOAD_FAST self
  LOAD_ATTR NULL|self + pluralize
  LOAD_FAST minutes
  LOAD_FAST lang_conf
  LOAD_CONST 'min_singular'
  BINARY_SUBSCR
  LOAD_FAST lang_conf
  LOAD_CONST 'min_plural'
  BINARY_SUBSCR
  CALL 3
  STORE_FAST minutes_str
  LOAD_FAST self
  LOAD_ATTR NULL|self + pluralize
  LOAD_FAST seconds
  LOAD_FAST lang_conf
  LOAD_CONST 'sec_singular'
  BINARY_SUBSCR
  LOAD_FAST lang_conf
  LOAD_CONST 'sec_plural'
  BINARY_SUBSCR
  CALL 3
  STORE_FAST seconds_str
  LOAD_FAST minutes
  LOAD_FAST content
  STORE_ATTR readtime
  LOAD_FAST minutes_str
  LOAD_FAST content
  STORE_ATTR readtime_string
  LOAD_FAST minutes
  LOAD_FAST seconds
  BUILD_TUPLE 2
  LOAD_FAST content
  STORE_ATTR readtime_with_seconds
  LOAD_CONST '{}, {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST minutes_str
  LOAD_FAST seconds_str
  CALL 2
  LOAD_FAST content
  STORE_ATTR readtime_string_with_seconds
  RETURN_CONST None
L2:
  RETURN_CONST None
END

def read_time(self, content):
    """pass"""
    if get_class_name(content) in self.content_type_supported:
        if hasattr(content, 'readtime'):
            return None
        default_lang_conf = self.lang_settings['default']
        lang_conf = self.lang_settings.get(content.lang, default_lang_conf)
        avg_reading_wpm = lang_conf['wpm']
        num_words = len(content._content.split())
        minutes = num_words // avg_reading_wpm
        seconds = int(num_words / avg_reading_wpm * 60 - minutes * 60)
        minutes_str = self.pluralize(minutes, lang_conf['min_singular'], lang_conf['min_plural'])
        seconds_str = self.pluralize(seconds, lang_conf['sec_singular'], lang_conf['sec_plural'])
        content.readtime = minutes
        content.readtime_string = minutes_str
        content.readtime_with_seconds = (minutes, seconds)
        content.readtime_string_with_seconds = '{}, {}'.format(minutes_str, seconds_str)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code pluralize>
  MAKE_FUNCTION 0
  STORE_NAME pluralize
  RETURN_CONST None
END
CODE pluralize(self, measure, singular, plural)
  DOC 'pass'
  RESUME 0
  LOAD_FAST measure
  LOAD_CONST 1
  COMPARE_OP ==
  POP_JUMP_IF_FALSE L1
  LOAD_CONST '{} {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST measure
  LOAD_FAST singular
  CALL 2
  RETURN_VALUE
L1:
  LOAD_CONST '{} {}'
  LOAD_ATTR NULL|self + format
  LOAD_FAST measure
  LOAD_FAST plural
  CALL 2
  RETURN_VALUE
END

def pluralize(self, measure, singular, plural):
    """pass"""
    if measure == 1:
        return '{} {}'.format(measure, singular)
    else:
        return '{} {}'.format(measure, plural)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code list_datasources>
  MAKE_FUNCTION 0
  STORE_NAME list_datasources
  RETURN_CONST None
END
CODE list_datasources(self, source_id)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url
  LOAD_CONST 'DATASOURCE'
  LOAD_CONST 'GET'
  LOAD_CONST 'multi'
  LOAD_CONST 'source_id'
  LOAD_FAST source_id
  BUILD_MAP 1
  CALL 4
  STORE_FAST target_url
  LOAD_GLOBAL base
  LOAD_ATTR NULL|self + Query
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_manager
  LOAD_GLOBAL Datasource
  CALL 1
  LOAD_FAST target_url
  CALL 2
  RETURN_VALUE
END

def list_datasources(self, source_id):
    """pass"""
    target_url = self.client.get_url('DATASOURCE', 'GET', 'multi', {'source_id': source_id})
    return base.Query(self.client.get_manager(Datasource), target_url)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code get_datasource>
  MAKE_FUNCTION 0
  STORE_NAME get_datasource
  RETURN_CONST None
END
CODE get_datasource(self, source_id, datasource_id)
  DOC 'pass'
  RESUME 0
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_url
  LOAD_CONST 'DATASOURCE'
  LOAD_CONST 'GET'
  LOAD_CONST 'single'
  LOAD_FAST source_id
  LOAD_FAST datasource_id
  LOAD_CONST ('source_id', 'datasource_id')
  BUILD_CONST_KEY_MAP 2
  CALL 4
  STORE_FAST target_url
  LOAD_FAST self
  LOAD_ATTR client
  LOAD_ATTR NULL|self + get_manager
  LOAD_GLOBAL Datasource
  CALL 1
  LOAD_ATTR NULL|self + _get
  LOAD_FAST target_url
  CALL 1
  RETURN_VALUE
END

def get_datasource(self, source_id, datasource_id):
    """pass"""
    target_url = self.client.get_url('DATASOURCE', 'GET', 'single', {'source_id': source_id, 'datasource_id': datasource_id})
    return self.client.get_manager(Datasource)._get(target_url)


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code open_store_variable>
  MAKE_FUNCTION 0
  STORE_NAME open_store_variable
  RETURN_CONST None
END
CODE open_store_variable(self, name, var)
  DOC 'pass'
  RESUME 0
  LOAD_GLOBAL indexing
  LOAD_ATTR NULL|self + LazilyOuterIndexedArray
  LOAD_GLOBAL NULL + CDMArrayWrapper
  LOAD_FAST name
  LOAD_FAST self
  CALL 2
  CALL 1
  STORE_FAST data
  LOAD_GLOBAL NULL + Variable
  LOAD_FAST var
  LOAD_ATTR dimensions
  LOAD_FAST data
  LOAD_FAST var
  LOAD_ATTR NULL|self + ncattrs
  CALL 0
  GET_ITER
  LOAD_FAST_AND_CLEAR a
  SWAP 2
L1:
  BUILD_MAP 0
  SWAP 2
L2:
  FOR_ITER L3
  STORE_FAST a
  LOAD_FAST a
  LOAD_GLOBAL NULL + getattr
  LOAD_FAST var
  LOAD_FAST a
  CALL 2
  MAP_ADD 2
  JUMP_BACKWARD L2
L3:
  END_FOR
L4:
  SWAP 2
  STORE_FAST a
  CALL 3
  RETURN_VALUE
L5:
  SWAP 2
  POP_TOP
  SWAP 2
  STORE_FAST a
  RERAISE 0
  EXC try=L1..L4 -> handler=L5 depth=6 lasti=False
END

def open_store_variable(self, name, var):
    """pass"""
    data = indexing.LazilyOuterIndexedArray(CDMArrayWrapper(name, self))
    return Variable(var.dimensions, data, {a: getattr(var, a) for a in var.ncattrs()})


Input:
CODE <module>()
  RESUME 0
  LOAD_CONST <code get_attrs>
  MAKE_FUNCTION 0
  STORE_NAME get_attrs
  RETURN_CONST None
END
CODE get_attrs(self)
  DOC 'pass'
  MAKE_CELL self
  RESUME 0
  LOAD_GLOBAL NULL + FrozenOrderedDict
  LOAD_CLOSURE self
  BUILD_TUPLE 1
  LOAD_CONST <code get_attrs.<locals>.<genexpr>>
  MAKE_FUNCTION closure
  LOAD_DEREF self
  LOAD_ATTR ds
  LOAD_ATTR NULL|self + ncattrs
  CALL 0
  GET_ITER
  CALL 0
  CALL 1
  RETURN_VALUE
END
CODE get_attrs.<locals>.<genexpr>(.0)
  COPY_FREE_VARS 1
  RETURN_GENERATOR
  POP_TOP
L1:
  RESUME 0
  LOAD_FAST .0
L2:
  FOR_ITER L3
  STORE_FAST a
  LOAD_FAST a
  LOAD_GLOBAL NULL + getattr
  LOAD_DEREF self
  LOAD_ATTR ds
  LOAD_FAST a
  CALL 2
  BUILD_TUPLE 2
  YIELD_VALUE 1
  RESUME 1
  POP_TOP
  JUMP_BACKWARD L2
L3:
  END_FOR
  RETURN_CONST None
L4:
  CALL_INTRINSIC_1 INTRINSIC_STOPITERATION_ERROR
  RERAISE 1
  EXC try=L1..L4 -> handler=L4 depth=0 lasti=True
END

def get_attrs(self):
    """pass"""
    return FrozenOrderedDict(((a, getattr(self.ds, a)) for a in self.ds.ncattrs()))