From 6c1803397da7917c04a3a559f37de7fd93d11fcb Mon Sep 17 00:00:00 2001 From: Michael Wiencek Date: Mon, 17 Oct 2011 14:33:38 -0500 Subject: [PATCH] Nuke track/release standardization options --- picard/mbxml.py | 38 +-- picard/ui/options/metadata.py | 6 - picard/ui/ui_options_metadata.py | 167 +---------- ui/options_metadata.ui | 469 +------------------------------ 4 files changed, 23 insertions(+), 657 deletions(-) diff --git a/picard/mbxml.py b/picard/mbxml.py index 136233f97..cccfed71f 100644 --- a/picard/mbxml.py +++ b/picard/mbxml.py @@ -52,10 +52,6 @@ def _decamelcase(text): return re.sub(r'([A-Z])', r' \1', text).strip() -def _setting(config, name): - return config and config.setting[name] - - _REPLACE_MAP = {} _EXTRA_ATTRS = ['guest', 'additional', 'minor'] def _parse_attributes(attrs): @@ -111,7 +107,7 @@ def _relations_to_metadata(relation_lists, m, config): def _translate_artist_node(node, config=None): transl = None - if _setting(config, 'translate_artist_names'): + if config and config.setting['translate_artist_names']: locale = config.setting["artist_locale"] lang = locale.split("_")[0] if "alias_list" in node.children: @@ -136,7 +132,7 @@ def artist_credit_from_node(node, config=None): if transl: artist += transl else: - if 'name' in credit.children and not _setting(config, "standardize_artists"): + if 'name' in credit.children and not (config and config.setting["standardize_artists"]): artist += credit.name[0].text else: artist += a.name[0].text @@ -188,21 +184,18 @@ def media_formats_from_node(node): def track_to_metadata(node, track, config): m = track.metadata recording_to_metadata(node.recording[0], track, config) - transl = m['releasestatus'] == "pseudo-release" # overwrite with data we have on the track for name, nodes in node.children.iteritems(): if not nodes: continue if name == 'title': - if not config.setting["standardize_tracks"] or transl: - m['title'] = nodes[0].text + m['title'] = nodes[0].text elif name == 'position': m['tracknumber'] = nodes[0].text elif name == 'length' and nodes[0].text: m.length = int(nodes[0].text) elif name == 'artist_credit': - if not config.setting["standardize_artists"] or transl: - artist_credit_to_metadata(nodes[0], m, config) + artist_credit_to_metadata(nodes[0], m, config) def recording_to_metadata(node, track, config): @@ -249,26 +242,21 @@ def medium_to_metadata(node, m): def release_to_metadata(node, m, config, album=None): """Make metadata dict from a XML 'release' node.""" m['musicbrainz_albumid'] = node.attribs['id'] - - if "status" in node.children: - m['releasestatus'] = node.status[0].text.lower() - transl = m['releasestatus'] == "pseudo-release" - for name, nodes in node.children.iteritems(): if not nodes: continue if name == 'release_group': release_group_to_metadata(nodes[0], m, config, album) + elif name == 'status': + m['releasestatus'] = nodes[0].text.lower() elif name == 'title': - if not config.setting["standardize_releases"] or transl: - m['album'] = nodes[0].text + m['album'] = nodes[0].text elif name == 'disambiguation': m['~releasecomment'] = nodes[0].text elif name == 'asin': m['asin'] = nodes[0].text elif name == 'artist_credit': - if not config.setting["standardize_artists"] or transl: - artist_credit_to_metadata(nodes[0], m, config, release=True) + artist_credit_to_metadata(nodes[0], m, config, release=True) elif name == 'date': m['date'] = nodes[0].text elif name == 'country': @@ -294,18 +282,10 @@ def release_group_to_metadata(node, m, config, album=None): """Make metadata dict from a XML 'release-group' node taken from inside a 'release' node.""" if 'type' in node.attribs: m['releasetype'] = node.type.lower() - transl = m['releasestatus'] == "pseudo-release" - for name, nodes in node.children.iteritems(): if not nodes: continue - if name == 'title': - if config.setting["standardize_releases"] and not transl: - m['album'] = node.title[0].text - elif name == 'artist_credit': - if config.setting["standardize_artists"] and not transl: - artist_credit_to_metadata(nodes[0], m, config, release=True) - elif name == 'first_release_date': + if name == 'first_release_date': m['originaldate'] = nodes[0].text elif name == 'tag_list': add_folksonomy_tags(nodes[0], album) diff --git a/picard/ui/options/metadata.py b/picard/ui/options/metadata.py index a74d041ef..6485b942c 100644 --- a/picard/ui/options/metadata.py +++ b/picard/ui/options/metadata.py @@ -41,8 +41,6 @@ class MetadataOptionsPage(OptionsPage): BoolOption("setting", "track_ars", False), BoolOption("setting", "folksonomy_tags", False), BoolOption("setting", "convert_punctuation", True), - BoolOption("setting", "standardize_tracks", False), - BoolOption("setting", "standardize_releases", False), BoolOption("setting", "standardize_artists", False), ] @@ -73,8 +71,6 @@ class MetadataOptionsPage(OptionsPage): self.ui.folksonomy_tags.setChecked(self.config.setting["folksonomy_tags"]) self.ui.va_name.setText(self.config.setting["va_name"]) self.ui.nat_name.setText(self.config.setting["nat_name"]) - self.ui.standardize_tracks.setChecked(self.config.setting["standardize_tracks"]) - self.ui.standardize_releases.setChecked(self.config.setting["standardize_releases"]) self.ui.standardize_artists.setChecked(self.config.setting["standardize_artists"]) def save(self): @@ -86,8 +82,6 @@ class MetadataOptionsPage(OptionsPage): self.config.setting["folksonomy_tags"] = self.ui.folksonomy_tags.isChecked() self.config.setting["va_name"] = self.ui.va_name.text() self.config.setting["nat_name"] = self.ui.nat_name.text() - self.config.setting["standardize_tracks"] = self.ui.standardize_tracks.isChecked() - self.config.setting["standardize_releases"] = self.ui.standardize_releases.isChecked() self.config.setting["standardize_artists"] = self.ui.standardize_artists.isChecked() def set_va_name_default(self): diff --git a/picard/ui/ui_options_metadata.py b/picard/ui/ui_options_metadata.py index d9eec53ac..1912d716b 100644 --- a/picard/ui/ui_options_metadata.py +++ b/picard/ui/ui_options_metadata.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ui/options_metadata.ui' # -# Created: Tue Oct 4 23:21:50 2011 +# Created: Mon Oct 17 14:24:15 2011 # by: PyQt4 UI code generator 4.8.5 # # WARNING! All changes made in this file will be lost! @@ -40,6 +40,9 @@ class Ui_MetadataOptionsPage(object): self.artist_locale = QtGui.QComboBox(self.rename_files) self.artist_locale.setObjectName(_fromUtf8("artist_locale")) self.verticalLayout_3.addWidget(self.artist_locale) + self.standardize_artists = QtGui.QCheckBox(self.rename_files) + self.standardize_artists.setObjectName(_fromUtf8("standardize_artists")) + self.verticalLayout_3.addWidget(self.standardize_artists) self.convert_punctuation = QtGui.QCheckBox(self.rename_files) self.convert_punctuation.setObjectName(_fromUtf8("convert_punctuation")) self.verticalLayout_3.addWidget(self.convert_punctuation) @@ -53,157 +56,6 @@ class Ui_MetadataOptionsPage(object): self.folksonomy_tags.setObjectName(_fromUtf8("folksonomy_tags")) self.verticalLayout_3.addWidget(self.folksonomy_tags) self.verticalLayout.addWidget(self.rename_files) - self.rename_files_2 = QtGui.QGroupBox(MetadataOptionsPage) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rename_files_2.sizePolicy().hasHeightForWidth()) - self.rename_files_2.setSizePolicy(sizePolicy) - self.rename_files_2.setMinimumSize(QtCore.QSize(397, 144)) - self.rename_files_2.setFlat(False) - self.rename_files_2.setObjectName(_fromUtf8("rename_files_2")) - self.gridLayout = QtGui.QGridLayout(self.rename_files_2) - self.gridLayout.setObjectName(_fromUtf8("gridLayout")) - self.label = QtGui.QLabel(self.rename_files_2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) - self.label.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.label.setFont(font) - self.label.setAlignment(QtCore.Qt.AlignCenter) - self.label.setObjectName(_fromUtf8("label")) - self.gridLayout.addWidget(self.label, 0, 1, 1, 3) - self.label_2 = QtGui.QLabel(self.rename_files_2) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.label_2.setFont(font) - self.label_2.setAlignment(QtCore.Qt.AlignCenter) - self.label_2.setObjectName(_fromUtf8("label_2")) - self.gridLayout.addWidget(self.label_2, 0, 4, 1, 3) - self.label_3 = QtGui.QLabel(self.rename_files_2) - self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight) - self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_3.setObjectName(_fromUtf8("label_3")) - self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1) - spacerItem = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem, 1, 1, 1, 1) - self.tracks_on_cover = QtGui.QRadioButton(self.rename_files_2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.tracks_on_cover.sizePolicy().hasHeightForWidth()) - self.tracks_on_cover.setSizePolicy(sizePolicy) - self.tracks_on_cover.setMinimumSize(QtCore.QSize(18, 18)) - self.tracks_on_cover.setLayoutDirection(QtCore.Qt.LeftToRight) - self.tracks_on_cover.setText(_fromUtf8("")) - self.tracks_on_cover.setIconSize(QtCore.QSize(16, 16)) - self.tracks_on_cover.setChecked(True) - self.tracks_on_cover.setObjectName(_fromUtf8("tracks_on_cover")) - self.buttonGroup = QtGui.QButtonGroup(MetadataOptionsPage) - self.buttonGroup.setObjectName(_fromUtf8("buttonGroup")) - self.buttonGroup.addButton(self.tracks_on_cover) - self.gridLayout.addWidget(self.tracks_on_cover, 1, 2, 1, 1) - spacerItem1 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem1, 1, 3, 1, 1) - spacerItem2 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem2, 1, 4, 1, 1) - self.standardize_tracks = QtGui.QRadioButton(self.rename_files_2) - self.standardize_tracks.setEnabled(True) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.standardize_tracks.sizePolicy().hasHeightForWidth()) - self.standardize_tracks.setSizePolicy(sizePolicy) - self.standardize_tracks.setMinimumSize(QtCore.QSize(18, 18)) - self.standardize_tracks.setText(_fromUtf8("")) - self.standardize_tracks.setObjectName(_fromUtf8("standardize_tracks")) - self.buttonGroup.addButton(self.standardize_tracks) - self.gridLayout.addWidget(self.standardize_tracks, 1, 5, 1, 1) - spacerItem3 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem3, 1, 6, 1, 1) - self.label_4 = QtGui.QLabel(self.rename_files_2) - self.label_4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_4.setObjectName(_fromUtf8("label_4")) - self.gridLayout.addWidget(self.label_4, 2, 0, 1, 1) - spacerItem4 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem4, 2, 1, 1, 1) - self.releases_on_cover = QtGui.QRadioButton(self.rename_files_2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.releases_on_cover.sizePolicy().hasHeightForWidth()) - self.releases_on_cover.setSizePolicy(sizePolicy) - self.releases_on_cover.setMinimumSize(QtCore.QSize(18, 18)) - self.releases_on_cover.setText(_fromUtf8("")) - self.releases_on_cover.setChecked(True) - self.releases_on_cover.setObjectName(_fromUtf8("releases_on_cover")) - self.buttonGroup_2 = QtGui.QButtonGroup(MetadataOptionsPage) - self.buttonGroup_2.setObjectName(_fromUtf8("buttonGroup_2")) - self.buttonGroup_2.addButton(self.releases_on_cover) - self.gridLayout.addWidget(self.releases_on_cover, 2, 2, 1, 1) - spacerItem5 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem5, 2, 3, 1, 1) - spacerItem6 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem6, 2, 4, 1, 1) - self.standardize_releases = QtGui.QRadioButton(self.rename_files_2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.standardize_releases.sizePolicy().hasHeightForWidth()) - self.standardize_releases.setSizePolicy(sizePolicy) - self.standardize_releases.setMinimumSize(QtCore.QSize(18, 18)) - self.standardize_releases.setText(_fromUtf8("")) - self.standardize_releases.setObjectName(_fromUtf8("standardize_releases")) - self.buttonGroup_2.addButton(self.standardize_releases) - self.gridLayout.addWidget(self.standardize_releases, 2, 5, 1, 1) - spacerItem7 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem7, 2, 6, 1, 1) - self.label_5 = QtGui.QLabel(self.rename_files_2) - self.label_5.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_5.setObjectName(_fromUtf8("label_5")) - self.gridLayout.addWidget(self.label_5, 3, 0, 1, 1) - spacerItem8 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem8, 3, 1, 1, 1) - self.artists_on_cover = QtGui.QRadioButton(self.rename_files_2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.artists_on_cover.sizePolicy().hasHeightForWidth()) - self.artists_on_cover.setSizePolicy(sizePolicy) - self.artists_on_cover.setMinimumSize(QtCore.QSize(18, 18)) - self.artists_on_cover.setText(_fromUtf8("")) - self.artists_on_cover.setIconSize(QtCore.QSize(16, 16)) - self.artists_on_cover.setChecked(True) - self.artists_on_cover.setObjectName(_fromUtf8("artists_on_cover")) - self.buttonGroup_3 = QtGui.QButtonGroup(MetadataOptionsPage) - self.buttonGroup_3.setObjectName(_fromUtf8("buttonGroup_3")) - self.buttonGroup_3.addButton(self.artists_on_cover) - self.gridLayout.addWidget(self.artists_on_cover, 3, 2, 1, 1) - spacerItem9 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem9, 3, 3, 1, 1) - spacerItem10 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem10, 3, 4, 1, 1) - self.standardize_artists = QtGui.QRadioButton(self.rename_files_2) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.standardize_artists.sizePolicy().hasHeightForWidth()) - self.standardize_artists.setSizePolicy(sizePolicy) - self.standardize_artists.setMinimumSize(QtCore.QSize(18, 18)) - self.standardize_artists.setText(_fromUtf8("")) - self.standardize_artists.setObjectName(_fromUtf8("standardize_artists")) - self.buttonGroup_3.addButton(self.standardize_artists) - self.gridLayout.addWidget(self.standardize_artists, 3, 5, 1, 1) - spacerItem11 = QtGui.QSpacerItem(33, 18, QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem11, 3, 6, 1, 1) - spacerItem12 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Minimum) - self.gridLayout.addItem(spacerItem12, 2, 7, 1, 1) - self.verticalLayout.addWidget(self.rename_files_2) self.rename_files_3 = QtGui.QGroupBox(MetadataOptionsPage) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) @@ -234,8 +86,8 @@ class Ui_MetadataOptionsPage(object): self.va_name.setObjectName(_fromUtf8("va_name")) self.gridlayout.addWidget(self.va_name, 1, 0, 1, 1) self.verticalLayout.addWidget(self.rename_files_3) - spacerItem13 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.MinimumExpanding) - self.verticalLayout.addItem(spacerItem13) + spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.MinimumExpanding) + self.verticalLayout.addItem(spacerItem) self.label_6.setBuddy(self.va_name_default) self.label_7.setBuddy(self.nat_name_default) @@ -249,16 +101,11 @@ class Ui_MetadataOptionsPage(object): def retranslateUi(self, MetadataOptionsPage): self.rename_files.setTitle(_("Metadata")) self.translate_artist_names.setText(_("Translate artist names to this locale where possible:")) + self.standardize_artists.setText(_("Use standardized artist names")) self.convert_punctuation.setText(_("Convert Unicode punctuation characters to ASCII")) self.release_ars.setText(_("Use release relationships")) self.track_ars.setText(_("Use track relationships")) self.folksonomy_tags.setText(_("Use folksonomy tags as genre")) - self.rename_files_2.setTitle(_("Standardization")) - self.label.setText(_("As on cover")) - self.label_2.setText(_("Standardized")) - self.label_3.setText(_("Track titles")) - self.label_4.setText(_("Release titles")) - self.label_5.setText(_("Artist names")) self.rename_files_3.setTitle(_("Custom Fields")) self.label_6.setText(_("Various artists:")) self.label_7.setText(_("Non-album tracks:")) diff --git a/ui/options_metadata.ui b/ui/options_metadata.ui index 773e133ce..d68121d5a 100644 --- a/ui/options_metadata.ui +++ b/ui/options_metadata.ui @@ -47,6 +47,13 @@ + + + + Use standardized artist names + + + @@ -78,468 +85,6 @@ - - - - - 0 - 0 - - - - - 397 - 144 - - - - Standardization - - - false - - - - - - - 0 - 0 - - - - - 75 - true - - - - As on cover - - - Qt::AlignCenter - - - - - - - - 75 - true - - - - Standardized - - - Qt::AlignCenter - - - - - - - Qt::LeftToRight - - - Track titles - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - Qt::LeftToRight - - - - - - - 16 - 16 - - - - true - - - buttonGroup - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - true - - - - 0 - 0 - - - - - 18 - 18 - - - - - - - buttonGroup - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - Release titles - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - - - true - - - buttonGroup_2 - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - - - buttonGroup_2 - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - Artist names - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - - - - 16 - 16 - - - - true - - - buttonGroup_3 - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - - 0 - 0 - - - - - 18 - 18 - - - - - - - buttonGroup_3 - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 33 - 18 - - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 40 - 20 - - - - - - -