예제 #1
0
def swap_attributes(config, powerline_module):
	return replace_attr(powerline_module, 'os', Args(
		path=Args(
			isfile=lambda path: path.lstrip('/').replace('.json', '') in config,
			join=os.path.join,
			expanduser=lambda path: path,
			realpath=lambda path: path,
			dirname=os.path.dirname,
		),
		environ={},
	))
 def test_tmux(self):
     from powerline.segments import common
     from imp import reload
     reload(common)
     from powerline.shell import ShellPowerline
     with replace_attr(common, 'urllib_read', urllib_read):
         with ShellPowerline(Args(ext=['tmux']),
                             logger=get_logger(),
                             run_once=False) as powerline:
             powerline.render()
         with ShellPowerline(Args(ext=['tmux']),
                             logger=get_logger(),
                             run_once=False) as powerline:
             powerline.render()
예제 #3
0
	def test_term_truecolor_escapes(self, config):
		from powerline.shell import ShellPowerline
		import powerline as powerline_module
		config['config']['common']['term_truecolor'] = True
		with swap_attributes(config, powerline_module):
			with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
				self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0;38;2;192;0;192;48;2;0;128;128m\xa0s\x1b[0;38;2;0;128;128;49;22m>>\x1b[0m')
예제 #4
0
	def test_screen_escapes(self, config):
		from powerline.shell import ShellPowerline
		import powerline as powerline_module
		config['config']['common']['additional_escapes'] = 'screen'
		with swap_attributes(config, powerline_module):
			with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
				self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0;38;5;5;48;5;6m\x1b\\\xa0s\x1bP\x1b\x1b[0;38;5;6;49;22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\')
예제 #5
0
	def test_fbterm_escapes(self, config):
		from powerline.shell import ShellPowerline
		import powerline as powerline_module
		config['config']['common']['term_escape_style'] = 'fbterm'
		with swap_attributes(config, powerline_module):
			with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
				self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0m\x1b[1;5}\x1b[2;6}\xa0s\x1b[0m\x1b[1;6}\x1b[49m\x1b[22m>>\x1b[0m')
    def test_ipython(self):
        from powerline.ipython import IPythonPowerline

        class IpyPowerline(IPythonPowerline):
            config_paths = None
            config_overrides = None
            theme_overrides = {}

        segment_info = Args(prompt_count=1)

        with IpyPowerline(logger=get_logger(),
                          renderer_module='.pre_5') as powerline:
            for prompt_type in ['in', 'in2']:
                powerline.render(is_prompt=True,
                                 matcher_info=prompt_type,
                                 segment_info=segment_info)
                powerline.render(is_prompt=True,
                                 matcher_info=prompt_type,
                                 segment_info=segment_info)
        with IpyPowerline(logger=get_logger(),
                          renderer_module='.pre_5') as powerline:
            for prompt_type in ['out', 'rewrite']:
                powerline.render(is_prompt=False,
                                 matcher_info=prompt_type,
                                 segment_info=segment_info)
                powerline.render(is_prompt=False,
                                 matcher_info=prompt_type,
                                 segment_info=segment_info)
예제 #7
0
 def test_escapes(self, config):
     from powerline.shell import ShellPowerline
     import powerline as powerline_module
     with swap_attributes(config, powerline_module):
         with get_powerline_raw(config,
                                ShellPowerline,
                                args=Args(config_path=[''])) as powerline:
             self.assertEqual(
                 powerline.render(segment_info={}, side='left'),
                 '\x1b[0;38;5;5;48;5;6m\xa0s\x1b[0;38;5;6;49;22m>>\x1b[0m')
예제 #8
0
    def test_no_attributes(self, p, config):
        def m1(divider=',', **kwargs):
            return divider.join(kwargs.keys()) + divider

        config['themes/test/default']['segments'] = {
            'left': [{
                'function': 'bar.m1'
            }]
        }
        with replace_item(sys.modules, 'bar', Args(m1=m1)):
            self.assertRenderEqual(p, '{56} pl,{6-}>>{--}')
예제 #9
0
    def test_exinclude_function(self, p, config):
        config['themes/test/default']['segments'] = {
            'left': [
                highlighted_string('s1', 'g1', exclude_function='mod.foo'),
                highlighted_string('s2',
                                   'g1',
                                   exclude_function='mod.foo',
                                   include_function='mod.bar'),
                highlighted_string('s3', 'g1', include_function='mod.bar'),
            ]
        }
        launched = set()
        fool = [None]
        barl = [None]

        def foo(*args, **kwargs):
            launched.add('foo')
            self.assertEqual(set(kwargs.keys()),
                             set(('pl', 'segment_info', 'mode')))
            self.assertEqual(args, ())
            return fool[0]

        def bar(*args, **kwargs):
            launched.add('bar')
            self.assertEqual(set(kwargs.keys()),
                             set(('pl', 'segment_info', 'mode')))
            self.assertEqual(args, ())
            return barl[0]

        with replace_item(sys.modules, 'mod', Args(foo=foo, bar=bar)):
            fool[0] = True
            barl[0] = True
            self.assertRenderEqual(p, '{56} s3{6-}>>{--}')
            self.assertEqual(launched, set(('foo', 'bar')))

            fool[0] = False
            barl[0] = True
            self.assertRenderEqual(p,
                                   '{56} s1{56}>{56}s2{56}>{56}s3{6-}>>{--}')
            self.assertEqual(launched, set(('foo', 'bar')))

            fool[0] = False
            barl[0] = False
            self.assertRenderEqual(p, '{56} s1{6-}>>{--}')
            self.assertEqual(launched, set(('foo', 'bar')))

            fool[0] = True
            barl[0] = False
            self.assertRenderEqual(p, '{--}')
            self.assertEqual(launched, set(('foo', 'bar')))
예제 #10
0
    def test_truncate(self, p, config):
        def m1(divider=',', **kwargs):
            return divider.join(kwargs.keys()) + divider

        def truncate(pl, amount, segment, **kwargs):
            return segment['contents'][:-amount]

        m1.truncate = truncate
        config['themes/test/default']['segments'] = {
            'left': [{
                'function': 'bar.m1'
            }]
        }
        with replace_item(sys.modules, 'bar', Args(m1=m1)):
            self.assertRenderEqual(p, '{56} p{6-}>>{--}', width=4)
예제 #11
0
    def test_expand(self, p, config):
        def m1(divider=',', **kwargs):
            return divider.join(kwargs.keys()) + divider

        def expand(pl, amount, segment, **kwargs):
            return ('-' * amount) + segment['contents']

        m1.expand = expand
        config['themes/test/default']['segments'] = {
            'left': [{
                'function': 'bar.m1',
                'width': 'auto'
            }]
        }
        with replace_item(sys.modules, 'bar', Args(m1=m1)):
            self.assertRenderEqual(p, '{56} ----pl,{6-}>>{--}', width=10)
 def test_bash(self):
     from powerline.shell import ShellPowerline
     args = Args(
         last_exit_code=1,
         jobnum=0,
         ext=['shell'],
         renderer_module='.bash',
         config_override={'ext': {
             'shell': {
                 'theme': 'default_leftonly'
             }
         }})
     with ShellPowerline(args, logger=get_logger(),
                         run_once=False) as powerline:
         powerline.render(segment_info={'args': args})
     with ShellPowerline(args, logger=get_logger(),
                         run_once=False) as powerline:
         powerline.render(segment_info={'args': args})
예제 #13
0
	def test_segment_data(self, p, config):
		def m1(**kwargs):
			return 'S'

		def m2(**kwargs):
			return 'S'
		sys.modules['bar'] = Args(m1=m1, m2=m2)
		config['themes/' + UT]['segment_data'] = {
			'm1': {
				'before': '1'
			},
			'bar.m2': {
				'before': '2'
			},
			'n': {
				'before': '3'
			},
			'm2': {
				'before': '4'
			},
		}
		config['themes/test/default']['segments'] = {
			'left': [
				{
					'function': 'bar.m1'
				},
				{
					'function': 'bar.m1',
					'name': 'n'
				},
				{
					'function': 'bar.m2',
					'name': 'n'
				},
				{
					'function': 'bar.m2'
				}
			]
		}
		self.assertRenderEqual(p, '{56} 1S{56}>{56}3S{610}>>{910}3S{910}>{910}2S{10-}>>{--}')
예제 #14
0
	def test_exinclude_modes_override_functions(self, p, config):
		config['themes/test/default']['segments'] = {
			'left': [
				highlighted_string('s1', 'g1', exclude_function='mod.foo', exclude_modes=['m2']),
				highlighted_string('s2', 'g1', exclude_function='mod.foo', include_modes=['m2']),
				highlighted_string('s3', 'g1', include_function='mod.foo', exclude_modes=['m2']),
				highlighted_string('s4', 'g1', include_function='mod.foo', include_modes=['m2']),
			]
		}
		fool = [None]

		def foo(*args, **kwargs):
			return fool[0]

		with replace_item(sys.modules, 'mod', Args(foo=foo)):
			fool[0] = True
			self.assertRenderEqual(p, '{56} s4{6-}>>{--}', mode='m2')
			self.assertRenderEqual(p, '{56} s3{56}>{56}s4{6-}>>{--}', mode='m1')

			fool[0] = False
			self.assertRenderEqual(p, '{56} s2{56}>{56}s4{6-}>>{--}', mode='m2')
			self.assertRenderEqual(p, '{56} s1{6-}>>{--}', mode='m1')
 def test_zsh(self):
     from powerline.shell import ShellPowerline
     args = Args(last_pipe_status=[1, 0],
                 jobnum=0,
                 ext=['shell'],
                 renderer_module='.zsh')
     segment_info = {'args': args}
     with ShellPowerline(args, logger=get_logger(),
                         run_once=False) as powerline:
         powerline.render(segment_info=segment_info)
     with ShellPowerline(args, logger=get_logger(),
                         run_once=False) as powerline:
         powerline.render(segment_info=segment_info)
     segment_info['local_theme'] = 'select'
     with ShellPowerline(args, logger=get_logger(),
                         run_once=False) as powerline:
         powerline.render(segment_info=segment_info)
     segment_info['local_theme'] = 'continuation'
     segment_info['parser_state'] = 'if cmdsubst'
     with ShellPowerline(args, logger=get_logger(),
                         run_once=False) as powerline:
         powerline.render(segment_info=segment_info)
예제 #16
0
    def test_segment_datas(self, p, config):
        def m1(divider=',', **kwargs):
            return divider.join(kwargs.keys()) + divider

        m1.powerline_segment_datas = {
            UT: {
                'args': {
                    'divider': ';'
                }
            },
            'ascii': {
                'args': {
                    'divider': '--'
                }
            }
        }
        config['themes/test/default']['segments'] = {
            'left': [{
                'function': 'bar.m1'
            }]
        }
        with replace_item(sys.modules, 'bar', Args(m1=m1)):
            self.assertRenderEqual(p, '{56} pl;{6-}>>{--}')
예제 #17
0
class TestI3WM(TestCase):
    workspaces = [
        Args(name='1: w1',
             output='LVDS1',
             focused=False,
             urgent=False,
             visible=False),
        Args(name='2: w2',
             output='LVDS1',
             focused=False,
             urgent=False,
             visible=True),
        Args(name='3: w3',
             output='HDMI1',
             focused=False,
             urgent=True,
             visible=True),
        Args(name='4: w4',
             output='DVI01',
             focused=True,
             urgent=True,
             visible=True),
    ]

    @staticmethod
    def get_workspaces():
        return iter(TestI3WM.workspaces)

    @staticmethod
    def get_outputs(pl):
        return iter([
            {
                'name': 'LVDS1'
            },
            {
                'name': 'HDMI1'
            },
            {
                'name': 'DVI01'
            },
        ])

    def test_output_lister(self):
        pl = Pl()
        with replace_attr(i3wm, 'get_connected_xrandr_outputs',
                          self.get_outputs):
            self.assertEqual(
                list(i3wm.output_lister(pl=pl, segment_info={'a': 1})), [
                    ({
                        'a': 1,
                        'output': 'LVDS1'
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'HDMI1'
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01'
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

    def test_workspace_lister(self):
        pl = Pl()
        with replace_attr(i3wm, 'get_i3_connection',
                          lambda: Args(get_workspaces=self.get_workspaces)):
            self.assertEqual(
                list(i3wm.workspace_lister(pl=pl, segment_info={'a': 1})), [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': self.workspaces[2],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': self.workspaces[3],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={'a': 1},
                                          output='LVDS1')),
                [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={
                                              'a': 1,
                                              'output': 'LVDS1'
                                          })),
                [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={
                                              'a': 1,
                                              'output': 'LVDS1'
                                          },
                                          output=False)),
                [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': self.workspaces[2],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': self.workspaces[3],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={'a': 1},
                                          only_show=['focused', 'urgent'])),
                [
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': self.workspaces[2],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': self.workspaces[3],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])
예제 #18
0
    def test_workspace_lister(self):
        pl = Pl()
        with replace_attr(i3wm, 'get_i3_connection',
                          lambda: Args(get_workspaces=self.get_workspaces)):
            self.assertEqual(
                list(i3wm.workspace_lister(pl=pl, segment_info={'a': 1})), [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': self.workspaces[2],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': self.workspaces[3],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={'a': 1},
                                          output='LVDS1')),
                [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={
                                              'a': 1,
                                              'output': 'LVDS1'
                                          })),
                [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={
                                              'a': 1,
                                              'output': 'LVDS1'
                                          },
                                          output=False)),
                [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[0],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': self.workspaces[1],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': self.workspaces[2],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': self.workspaces[3],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={'a': 1},
                                          only_show=['focused', 'urgent'])),
                [
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': self.workspaces[2],
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': self.workspaces[3],
                    }, {
                        'draw_inner_divider': None
                    }),
                ])
예제 #19
0
    def test_workspace_lister(self):
        pl = Pl()
        with replace_attr(i3wm, 'get_i3_connection',
                          lambda: Args(get_workspaces=self.get_workspaces)):
            self.assertEqual(
                list(i3wm.workspace_lister(pl=pl, segment_info={'a': 1})), [
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': {
                            'name': '1: w1',
                            'focused': False,
                            'urgent': False,
                            'visible': False
                        }
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'LVDS1',
                        'workspace': {
                            'name': '2: w2',
                            'focused': False,
                            'urgent': False,
                            'visible': True
                        }
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'HDMI1',
                        'workspace': {
                            'name': '3: w3',
                            'focused': False,
                            'urgent': True,
                            'visible': True
                        }
                    }, {
                        'draw_inner_divider': None
                    }),
                    ({
                        'a': 1,
                        'output': 'DVI01',
                        'workspace': {
                            'name': '4: w4',
                            'focused': True,
                            'urgent': True,
                            'visible': True
                        }
                    }, {
                        'draw_inner_divider': None
                    }),
                ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={'a': 1},
                                          output='LVDS1')), [
                                              ({
                                                  'a': 1,
                                                  'output': 'LVDS1',
                                                  'workspace': {
                                                      'name': '1: w1',
                                                      'focused': False,
                                                      'urgent': False,
                                                      'visible': False
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                              ({
                                                  'a': 1,
                                                  'output': 'LVDS1',
                                                  'workspace': {
                                                      'name': '2: w2',
                                                      'focused': False,
                                                      'urgent': False,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                          ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={
                                              'a': 1,
                                              'output': 'LVDS1'
                                          })), [
                                              ({
                                                  'a': 1,
                                                  'output': 'LVDS1',
                                                  'workspace': {
                                                      'name': '1: w1',
                                                      'focused': False,
                                                      'urgent': False,
                                                      'visible': False
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                              ({
                                                  'a': 1,
                                                  'output': 'LVDS1',
                                                  'workspace': {
                                                      'name': '2: w2',
                                                      'focused': False,
                                                      'urgent': False,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                          ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={
                                              'a': 1,
                                              'output': 'LVDS1'
                                          },
                                          output=False)), [
                                              ({
                                                  'a': 1,
                                                  'output': 'LVDS1',
                                                  'workspace': {
                                                      'name': '1: w1',
                                                      'focused': False,
                                                      'urgent': False,
                                                      'visible': False
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                              ({
                                                  'a': 1,
                                                  'output': 'LVDS1',
                                                  'workspace': {
                                                      'name': '2: w2',
                                                      'focused': False,
                                                      'urgent': False,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                              ({
                                                  'a': 1,
                                                  'output': 'HDMI1',
                                                  'workspace': {
                                                      'name': '3: w3',
                                                      'focused': False,
                                                      'urgent': True,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                              ({
                                                  'a': 1,
                                                  'output': 'DVI01',
                                                  'workspace': {
                                                      'name': '4: w4',
                                                      'focused': True,
                                                      'urgent': True,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                          ])

            self.assertEqual(
                list(
                    i3wm.workspace_lister(pl=pl,
                                          segment_info={'a': 1},
                                          only_show=['focused', 'urgent'])), [
                                              ({
                                                  'a': 1,
                                                  'output': 'HDMI1',
                                                  'workspace': {
                                                      'name': '3: w3',
                                                      'focused': False,
                                                      'urgent': True,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                              ({
                                                  'a': 1,
                                                  'output': 'DVI01',
                                                  'workspace': {
                                                      'name': '4: w4',
                                                      'focused': True,
                                                      'urgent': True,
                                                      'visible': True
                                                  }
                                              }, {
                                                  'draw_inner_divider': None
                                              }),
                                          ])