issuekey ... storypoints
0 29688087 ... 1
1 29682716 ... 1
2 29644971 ... 1
3 29494181 ... 1
4 29437529 ... 1
[5 rows x 5 columns]
(355, 5)
Este conjunto de dados tem 355 observações. Cada observação é uma
User Story do Projeto 7764. O conjunto de dados tem 5 colunas.
storypoints context
0 1 Update templates for website merge requestsRel...
1 1 Make sure that we Capture Advanced Search in o...
2 1 Propose new IA for Brand and Digital Handbook#...
3 1 Cache `node_modules` for www-gitlab-com pipeli...
4 1 Disable all remaining unnecessary jobs in pipe...
valures Contagem
0 0 1
1 1 167
2 2 80
3 3 54
4 4 15
5 5 17
6 6 1
7 7 2
8 8 9
9 10 6
10 24 1
11 32 1
12 128 1
count 355.000000
mean 2.732394
std 7.186298
min 0.000000
25% 1.000000
50% 2.000000
75% 3.000000
max 128.000000
Name: storypoints, dtype: float64
A grande maioria das User Story. 75% da amostra foi medido como 1, 2
ou 3 Story Points.
<Figure size 800x600 with 0 Axes>
<AxesSubplot: >
Text(0.5, 1.0, 'Value Counts dos Story Points do Projeto 7764')
Text(0.5, 0, 'Valores do Story Point')
Text(0, 0.5, 'Contagem de vezes dos Story Points')

<Figure size 800x200 with 0 Axes>
{'whiskers': [<matplotlib.lines.Line2D object at 0x0000022113C614E0>, <matplotlib.lines.Line2D object at 0x0000022113C61780>], 'caps': [<matplotlib.lines.Line2D object at 0x0000022113C61A20>, <matplotlib.lines.Line2D object at 0x0000022113C61CC0>], 'boxes': [<matplotlib.lines.Line2D object at 0x0000022113C61240>], 'medians': [<matplotlib.lines.Line2D object at 0x0000022113C61F60>], 'fliers': [<matplotlib.lines.Line2D object at 0x0000022113C62200>], 'means': []}
Text(0.5, 1.0, 'Boxplot da Coluna Story Point')
Text(0.5, 0, 'Valores do Story Point')

Existem outliers nos Story Points, ou seja alguns Story Points são
distantes da média mais do que 2 desvios padrão.
storypoints context
0 1 Update templates for website merge requestsRel...
1 1 Make sure that we Capture Advanced Search in o...
2 1 Propose new IA for Brand and Digital Handbook#...
3 1 Cache `node_modules` for www-gitlab-com pipeli...
4 1 Disable all remaining unnecessary jobs in pipe...
<Figure size 800x200 with 0 Axes>
{'whiskers': [<matplotlib.lines.Line2D object at 0x0000022113CAB790>, <matplotlib.lines.Line2D object at 0x0000022113CABA30>], 'caps': [<matplotlib.lines.Line2D object at 0x0000022113CABCD0>, <matplotlib.lines.Line2D object at 0x0000022113CABF70>], 'boxes': [<matplotlib.lines.Line2D object at 0x0000022113CAB4F0>], 'medians': [<matplotlib.lines.Line2D object at 0x0000022113CD8250>], 'fliers': [<matplotlib.lines.Line2D object at 0x0000022113CD84F0>], 'means': []}
Text(0.5, 1.0, 'Boxplot dos Story Points do Projeto 7764 depois da remoção dos outliers')

<Figure size 800x600 with 0 Axes>
<AxesSubplot: >
Text(0.5, 1.0, 'Value Counts dos Story Points do Projeto 7764')
Text(0.5, 0, 'Valores do Story Point')
Text(0, 0.5, 'Contagem de vezes dos Story Points')

2.158536585365854
A média de Story Point de todo o conjunto de dados é de 2.15 Story
Point
1.3193741371375978
o MAE é de 1.31, quando utilizamos a média dos Story Points. Ou seja,
o Erro médo absoluto é de 1.28 SP quando sempre utilizamos um valor
fixo, lembrando que foi utilizado todo o conjunto de dados.
modelo MAE Teste color
0 Media 1.319374 blue
df_results
<string>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
<string>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
<string>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
<string>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
<string>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
<string>:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
SVR()
<string>:1: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
modelo MAE Teste color
0 Media 1.319374 blue
1 Legibility SVM 1.221740 orange
O MAE do modelo preditivo legibility é menor do que o MAE, quando
utilizamos a média dos Story Poits.
SVR()
<string>:1: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
modelo MAE Teste color
0 Media 1.319374 blue
1 Legibility SVM 1.221740 orange
2 TF-IDF SVM 1.270728 green
<Figure size 640x480 with 0 Axes>
<BarContainer object of 3 artists>
Text(0.5, 1.0, 'Comparação do MAE entre os modelos')
Text(0.5, 0, 'Modelos')
Text(0, 0.5, 'MAE')
(1.1, 1.4)

LS0tDQp0aXRsZTogIkFuw6FsaXNlIEV4cGxvcmF0w7NyaW8gUHJvamV0byA3NzY0Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQphdXRob3I6ICdHaXNlbGRvIGRhIFNpbHZhIE7DqW8nDQotLS0NCg0KYGBge3B5dGhvbiBlY2hvPUZBTFNFfQ0KaW1wb3J0IHBhbmRhcyBhcyBwZA0KaW1wb3J0IG1hdHBsb3RsaWIucHlwbG90IGFzIHBsdA0KZnJvbSB0ZXh0YmxvYiBpbXBvcnQgVGV4dEJsb2INCmltcG9ydCB0ZXh0c3RhdA0KZnJvbSBza2xlYXJuLnN2bSBpbXBvcnQgU1ZSDQpmcm9tIHNrbGVhcm4uZmVhdHVyZV9leHRyYWN0aW9uLnRleHQgaW1wb3J0IFRmaWRmVmVjdG9yaXplcg0KYGBgDQoNCmBgYHtweXRob24gIGVjaG89RkFMU0V9DQppbXBvcnQgbG9nZ2luZzsgDQpsb2dnaW5nLmdldExvZ2dlcigpLnNldExldmVsKGxvZ2dpbmcuQ1JJVElDQUwpDQpgYGANCg0KYGBge3B5dGhvbiAgZWNobz1GQUxTRX0NCm5hbWUgPSAnNzc2NCcNCmZpbGVuYW1lID0gJy4uL2RhdGEve30uY3N2Jy5mb3JtYXQobmFtZSkNCmRmID0gcGQucmVhZF9jc3YoZmlsZW5hbWUpDQpkZi5oZWFkKCkNCmBgYA0KDQpgYGB7cHl0aG9uIGVjaG89RmFsc2V9DQpkZi5zaGFwZQ0KYGBgDQoNCkVzdGUgY29uanVudG8gZGUgZGFkb3MgdGVtIDM1NSBvYnNlcnZhw6fDtWVzLiBDYWRhIG9ic2VydmHDp8OjbyDDqSB1bWEgVXNlciBTdG9yeSBkbyBQcm9qZXRvIDc3NjQuIE8gY29uanVudG8gZGUgZGFkb3MgdGVtIDUgY29sdW5hcy4NCg0KYGBge3B5dGhvbiBlY2hvPUZhbHNlfQ0KZGZbImNvbnRleHQiXSA9IGRmWyJ0aXRsZSJdICsgZGZbImRlc2NyaXB0aW9uIl0NCmRmID0gZGYuZHJvcChbJ2NyZWF0ZWQnLCAnaXNzdWVrZXknLCAndGl0bGUnLCAnZGVzY3JpcHRpb24nXSwgYXhpcz0xKQ0KZGZbJ2NvbnRleHQnXSA9IGRmWydjb250ZXh0J10uYXN0eXBlKHN0cikNCmRmLmhlYWQoKQ0KYGBgDQoNCmBgYHtweXRob24gZWNobz1GYWxzZX0NCnZhbHVlX2NvdW50ID0gZGZbJ3N0b3J5cG9pbnRzJ10udmFsdWVfY291bnRzKCkuc29ydF9pbmRleCgpDQpkZl92YWx1ZV9jb3VudCA9IHBkLkRhdGFGcmFtZShkYXRhID0geyd2YWx1cmVzJzogdmFsdWVfY291bnQuaW5kZXgsICdDb250YWdlbSc6IHZhbHVlX2NvdW50LnZhbHVlc30pDQpkZl92YWx1ZV9jb3VudA0KYGBgDQoNCmBgYHtweXRob24gZWNobz1GYWxzZX0NCmRmWydzdG9yeXBvaW50cyddLmRlc2NyaWJlKCkNCmBgYA0KQSBncmFuZGUgbWFpb3JpYSBkYXMgVXNlciBTdG9yeS4gNzUlIGRhIGFtb3N0cmEgZm9pIG1lZGlkbyBjb21vIDEsIDIgb3UgMyBTdG9yeSBQb2ludHMuDQoNCg0KYGBge3B5dGhvbiBlY2hvPUZhbHNlfQ0KcGx0LmZpZ3VyZShmaWdzaXplPSg4LCA2KSkNCnZhbHVlX2NvdW50LnBsb3Qoa2luZD0nYmFyJykNCnBsdC50aXRsZSgnVmFsdWUgQ291bnRzIGRvcyBTdG9yeSBQb2ludHMgZG8gUHJvamV0byA3NzY0JykNCnBsdC54bGFiZWwoJ1ZhbG9yZXMgZG8gU3RvcnkgUG9pbnQnKQ0KcGx0LnlsYWJlbCgnQ29udGFnZW0gZGUgdmV6ZXMgZG9zIFN0b3J5IFBvaW50cycpDQpwbHQuc2hvdygpDQpgYGANCg0KYGBge3B5dGhvbiBlY2hvPUZhbHNlfQ0KcGx0LmZpZ3VyZShmaWdzaXplPSg4LCAyKSkNCnBsdC5ib3hwbG90KGRmWydzdG9yeXBvaW50cyddLCB2ZXJ0PUZhbHNlKQ0KcGx0LnRpdGxlKCdCb3hwbG90IGRhIENvbHVuYSBTdG9yeSBQb2ludCcpDQpwbHQueGxhYmVsKCdWYWxvcmVzIGRvIFN0b3J5IFBvaW50JykNCnBsdC5zaG93KCkNCmBgYA0KDQpFeGlzdGVtIG91dGxpZXJzIG5vcyBTdG9yeSBQb2ludHMsIG91IHNlamEgYWxndW5zIFN0b3J5IFBvaW50cyBzw6NvIGRpc3RhbnRlcyBkYSBtw6lkaWEgbWFpcyBkbyBxdWUgMiBkZXN2aW9zIHBhZHLDo28uDQoNCg0KYGBge3B5dGhvbiBlY2hvPUZhbHNlfQ0KbWVhbiA9IGRmWydzdG9yeXBvaW50cyddLm1lYW4oKQ0Kc3RkX2RldiA9IGRmWydzdG9yeXBvaW50cyddLnN0ZCgpDQpvdXRsaWVyX2N1dG9mZiA9IDIgKiBzdGRfZGV2DQpkZl9jbGVhbiA9IGRmWyhkZlsnc3Rvcnlwb2ludHMnXSA+PSBtZWFuIC0gb3V0bGllcl9jdXRvZmYpICYgKGRmWydzdG9yeXBvaW50cyddIDw9IG1lYW4gKyBvdXRsaWVyX2N1dG9mZildDQpkZl9jbGVhbi5oZWFkKCkNCmBgYA0KDQpgYGB7cHl0aG9uIGVjaG89RkFMU0V9DQpwbHQuZmlndXJlKGZpZ3NpemU9KDgsMikpDQpwbHQuYm94cGxvdChkZl9jbGVhblsnc3Rvcnlwb2ludHMnXSwgdmVydD1GYWxzZSkNCnBsdC50aXRsZSgnQm94cGxvdCBkb3MgU3RvcnkgUG9pbnRzIGRvIFByb2pldG8gNzc2NCBkZXBvaXMgZGEgcmVtb8Onw6NvIGRvcyBvdXRsaWVycycpDQpwbHQuc2hvdygpDQpgYGANCg0KYGBge3B5dGhvbiBlY2hvPUZBTFNFfQ0KdmFsdWVfY291bnQgPSBkZl9jbGVhblsnc3Rvcnlwb2ludHMnXS52YWx1ZV9jb3VudHMoKS5zb3J0X2luZGV4KCkNCnBsdC5maWd1cmUoZmlnc2l6ZT0oOCwgNikpDQp2YWx1ZV9jb3VudC5wbG90KGtpbmQ9J2JhcicpDQpwbHQudGl0bGUoJ1ZhbHVlIENvdW50cyBkb3MgU3RvcnkgUG9pbnRzIGRvIFByb2pldG8gNzc2NCcpDQpwbHQueGxhYmVsKCdWYWxvcmVzIGRvIFN0b3J5IFBvaW50JykNCnBsdC55bGFiZWwoJ0NvbnRhZ2VtIGRlIHZlemVzIGRvcyBTdG9yeSBQb2ludHMnKQ0KcGx0LnNob3coKQ0KYGBgDQoNCmBgYHtweXRob24gZWNobz1GYWxzZX0NCiMgc2VwYXJhw6fDo28gdHJlaW5vIGUgdGVzdGUNCm51bV9saW5oYXNfdHJlaW5vID0gaW50KGxlbihkZl9jbGVhbikgKiAwLjcpDQpkYWRvc190cmVpbm8gPSBkZl9jbGVhbi5pbG9jWzpudW1fbGluaGFzX3RyZWlub10NCmRhZG9zX3Rlc3RlID0gZGZfY2xlYW4uaWxvY1tudW1fbGluaGFzX3RyZWlubzpdDQpgYGANCg0KYGBge3B5dGhvbiBlY2hvPUZhbHNlfQ0KbWVkaWFfc3AgPSBkYWRvc190cmVpbm9bJ3N0b3J5cG9pbnRzJ10ubWVhbigpDQptZWRpYV9zcA0KYGBgDQoNCkEgbcOpZGlhIGRlIFN0b3J5IFBvaW50IGRlIHRvZG8gbyBjb25qdW50byBkZSBkYWRvcyDDqSBkZSAyLjE1IFN0b3J5IFBvaW50DQoNCmBgYHtweXRob24gZWNobz1GYWxzZX0NCmRlZiBtZWFuX2Fic29sdXRlX2Vycm9yKHlfdHJ1ZSwgeV9wcmVkKToNCiAgIiIiDQogIENhbGN1bGEgbyBNZWFuIEFic29sdXRlIEVycm9yIChNQUUpLCBlbnRyZSBvcyB2YWxvcmVzIHZlcmRhZGVpcm9zICh5X3RydWUpIGUgb3MgdmFsb3JlcyBwcmV2aXN0b3MgKHlfcHJlZCkNCg0KICBBcmdzOg0KICAgIHlfdHJ1ZTogVW1hIGxpc3RhIG91IGFycmF5IE51bXB5IGRvcyB2YWxvcmVzIHZlcmRhZGVpcm9zLg0KICAgIHlfcHJlZDogVW1hIGxpc3RhIG91IGFycmF5IE51bVB5IGRvcyB2YWxvcmVzIHByZXZpc3Rvcy4NCg0KICBSZXR1cm5zOg0KICAgIG1hZTogTyBNZWFuIEFic29sdXRlIEVycm9yIGVudHJlIHlfdHJ1ZSBlIHlfcHJlZA0KICAiIiINCiAgaWYgbGVuKHlfdHJ1ZSkgIT0gbGVuKHlfcHJlZCk6DQogICAgcmFpc2UgVmFsdWVFcnJvcignT3MgdGFtYW5ob3MgZGUgeV90cnVlIGUgeV9wcmVkIGRldmVtIHNlciBpZ3VhaXMnKQ0KICBhYnNvbHV0ZV9FcnJvcnMgPVthYnModHJ1ZS1wcmVkKSBmb3IgdHJ1ZSwgcHJlZCBpbiB6aXAoeV90cnVlLCB5X3ByZWQpXQ0KICBtYWUgPSBzdW0oYWJzb2x1dGVfRXJyb3JzKSAvIGxlbih5X3RydWUpDQogIHJldHVybiBtYWUNCmBgYA0KDQoNCmBgYHtweXRob24gZWNobz1GYWxzZX0NCmxpc3RhX3lfcHJlZCA9IFttZWRpYV9zcF0gKiBsZW4oZGFkb3NfdGVzdGUpDQptYWVfbWVkaWFfc3AgPSBtZWFuX2Fic29sdXRlX2Vycm9yKGRhZG9zX3Rlc3RlWydzdG9yeXBvaW50cyddLCBsaXN0YV95X3ByZWQpDQptYWVfbWVkaWFfc3ANCmBgYA0KDQpvIE1BRSDDqSBkZSAxLjMxLCBxdWFuZG8gdXRpbGl6YW1vcyBhIG3DqWRpYSBkb3MgU3RvcnkgUG9pbnRzLiBPdSBzZWphLCBvIEVycm8gbcOpZG8gYWJzb2x1dG8gw6kgZGUgMS4yOCBTUCBxdWFuZG8gc2VtcHJlIHV0aWxpemFtb3MgdW0gdmFsb3IgZml4bywgbGVtYnJhbmRvIHF1ZSBmb2kgdXRpbGl6YWRvIHRvZG8gbyBjb25qdW50byBkZSBkYWRvcy4gDQoNCmBgYHtweXRob24gZWNobz1GQUxTRX0NCmRmX3Jlc3VsdHMgPSBwZC5EYXRhRnJhbWUoZGF0YT1bWydNZWRpYScsIG1hZV9tZWRpYV9zcCwgJ2JsdWUnXV0sIGNvbHVtbnM9Wydtb2RlbG8nLCAnTUFFIFRlc3RlJywgImNvbG9yIl0pDQpkZl9yZXN1bHRzDQpgYGANCg0KZGZfcmVzdWx0cw0KDQpgYGB7cHl0aG9uIGVjaG89RmFsc2V9DQpjb2x1bmFzID0gWydndW5uaW5nX2ZvZycsICdwb2xhcml0eScsJ3N1YmplY3Rpdml0eSddDQoNCmRhZG9zX3RyZWlub1snZ3VubmluZ19mb2cnXSA9IGRhZG9zX3RyZWlub1snY29udGV4dCddLmFwcGx5KHRleHRzdGF0Lmd1bm5pbmdfZm9nKQ0KZGFkb3NfdHJlaW5vWydwb2xhcml0eSddID0gZGFkb3NfdHJlaW5vWydjb250ZXh0J10uYXBwbHkobGFtYmRhIHg6IFRleHRCbG9iKHgpLnNlbnRpbWVudC5wb2xhcml0eSkNCmRhZG9zX3RyZWlub1snc3ViamVjdGl2aXR5J10gPSBkYWRvc190cmVpbm9bJ2NvbnRleHQnXS5hcHBseShsYW1iZGEgeDogVGV4dEJsb2IoeCkuc2VudGltZW50LnN1YmplY3Rpdml0eSkNCg0KZGFkb3NfdGVzdGVbJ2d1bm5pbmdfZm9nJ10gPSBkYWRvc190ZXN0ZVsnY29udGV4dCddLmFwcGx5KHRleHRzdGF0Lmd1bm5pbmdfZm9nKQ0KZGFkb3NfdGVzdGVbJ3BvbGFyaXR5J10gPSBkYWRvc190ZXN0ZVsnY29udGV4dCddLmFwcGx5KGxhbWJkYSB4OiBUZXh0QmxvYih4KS5zZW50aW1lbnQucG9sYXJpdHkpDQpkYWRvc190ZXN0ZVsnc3ViamVjdGl2aXR5J10gPSBkYWRvc190ZXN0ZVsnY29udGV4dCddLmFwcGx5KGxhbWJkYSB4OiBUZXh0QmxvYih4KS5zZW50aW1lbnQuc3ViamVjdGl2aXR5KQ0KYGBgDQoNCmBgYHtweXRob24gZWNobz1GQUxTRX0NCm1vZGVsID0gU1ZSKCkNCm1vZGVsLmZpdChkYWRvc190cmVpbm9bY29sdW5hc10sIGRhZG9zX3RyZWlub1snc3Rvcnlwb2ludHMnXSkNCnlfcHJlZCA9IG1vZGVsLnByZWRpY3QoZGFkb3NfdGVzdGVbY29sdW5hc10pDQptYWVfbGVnID0gbWVhbl9hYnNvbHV0ZV9lcnJvcihkYWRvc190ZXN0ZVsnc3Rvcnlwb2ludHMnXSwgeV9wcmVkKQ0KZGZfcmVzdWx0cyA9IGRmX3Jlc3VsdHMuYXBwZW5kKHsnbW9kZWxvJzonTGVnaWJpbGl0eSBTVk0nLCAnTUFFIFRlc3RlJzogbWFlX2xlZywgJ2NvbG9yJzogJ29yYW5nZSd9LCBpZ25vcmVfaW5kZXg9VHJ1ZSkNCmRmX3Jlc3VsdHMNCmBgYA0KDQpPIE1BRSBkbyBtb2RlbG8gcHJlZGl0aXZvIGxlZ2liaWxpdHkgw6kgbWVub3IgZG8gcXVlIG8gTUFFLCBxdWFuZG8gdXRpbGl6YW1vcyBhIG3DqWRpYSBkb3MgU3RvcnkgUG9pdHMuDQoNCmBgYHtweXRob24gZWNobz1GQUxTRX0NCnZlYyA9IFRmaWRmVmVjdG9yaXplcihtYXhfZmVhdHVyZXM9NTApDQp0ZmlkZl9tYXRyaXhfdHJlaW5vID0gdmVjLmZpdF90cmFuc2Zvcm0oZGFkb3NfdHJlaW5vWydjb250ZXh0J10pDQp0ZmlkZl9tYXRyaXhfdGVzdGUgPSB2ZWMudHJhbnNmb3JtKGRhZG9zX3Rlc3RlWydjb250ZXh0J10pDQpgYGANCg0KYGBge3B5dGhvbiBlY2hvPUZBTFNFfQ0KbW9kZWwgPSBTVlIoKQ0KbW9kZWwuZml0KHRmaWRmX21hdHJpeF90cmVpbm8sIGRhZG9zX3RyZWlub1snc3Rvcnlwb2ludHMnXSkNCnlfcHJlZCA9IG1vZGVsLnByZWRpY3QodGZpZGZfbWF0cml4X3Rlc3RlKQ0KbWFlX3RmaWRmID0gbWVhbl9hYnNvbHV0ZV9lcnJvcihkYWRvc190ZXN0ZVsnc3Rvcnlwb2ludHMnXSwgeV9wcmVkKQ0KZGZfcmVzdWx0cyA9IGRmX3Jlc3VsdHMuYXBwZW5kKHsnbW9kZWxvJzonVEYtSURGIFNWTScsICdNQUUgVGVzdGUnOiBtYWVfdGZpZGYsICdjb2xvcic6ICdncmVlbid9LCBpZ25vcmVfaW5kZXg9VHJ1ZSkNCmRmX3Jlc3VsdHMNCmBgYA0KYGBge3B5dGhvbiBlY2hvPUZBTFNFfQ0KcGx0LmZpZ3VyZSgpDQpkZl9yZXN1bHRzID0gZGZfcmVzdWx0cy5zb3J0X3ZhbHVlcyhieT0nTUFFIFRlc3RlJykNCnBsdC5iYXIoZGZfcmVzdWx0c1snbW9kZWxvJ10sIGRmX3Jlc3VsdHNbJ01BRSBUZXN0ZSddLCBjb2xvcj1kZl9yZXN1bHRzWydjb2xvciddKQ0KcGx0LnRpdGxlKCdDb21wYXJhw6fDo28gZG8gTUFFIGVudHJlIG9zIG1vZGVsb3MnKQ0KcGx0LnhsYWJlbCgnTW9kZWxvcycpDQpwbHQueWxhYmVsKCdNQUUnKQ0KcGx0LnlsaW0oMS4xLCAxLjQpDQpwbHQuc2hvdygpDQpgYGANCg==